内容纲要

在移动端开发中,APP间的跳转功能是必不可少的。然而,当涉及到从一个APP跳转到另一个APP,并且需要传递某些信息时,安全性就变得尤为重要。本文将探讨如何在实现APP间跳转功能,重点包括APP跳转的技术方案、以及确保数据安全性的方案设计。

背景

在许多应用场景中,我们需要实现从一个APP跳转到另一个APP,并传递一些数据。例如,用户在一个电商APP浏览商品后,点击一个按钮跳转到另一个支付APP完成支付。在这个过程中,我们需要将一些用户信息,如用户ID、订单详情等,传递给目标APP。然而,这些信息往往被视为隐私数据,如果以明文形式传递,可能会引发安全问题。因此,如何在APP间跳转时安全地携带和传输这些数据,成为了移动开发者必须面对的挑战。

跳转方案

数据传递方式

对于APP间跳转的数据传递方式,可以考虑使用URL Scheme或Universal Links来实现。这些方案允许我们通过在URL中携带参数的方式,将数据从一个APP传递到另一个APP。为了确保数据的安全性,我们可以对URL参数进行加密处理,然后在目标APP中进行解密。

URL Scheme

URL Scheme是一种APP特有的标识,通过这个标识,我们可以直接打开已经安装在用户设备上的特定APP。例如,微信的URL Scheme是weixin://,当用户在网页或其他应用中点击这个链接时,如果手机中已经安装了微信,它会自动打开微信。

值得注意的是,APP的URL Scheme是APP开发者定义的,却不是必须定义的。这意味着不是所有的APP都可以通过这种方式进行跳转。同时该标识也没有重复校验,这意味着如果手机中安装的多种APP具有同样的URL Scheme,跳转就会产生问题。

Universal Links

Universal Links是一种更为先进的跳转方式。它的基本原理是使用标准的http或https链接,这些链接直接指向特定的域名。当APP支持Universal Links时,用户点击这些链接,如果设备上已经安装了该APP,它会自动打开。

数据加密方式

在进行APP间跳转时,无论采用URL Scheme还是Universal Links,都需要确保携带的数据安全。为了对传递的信息进行加密,可以采用结合AES加密和时间戳的方案。在跳转过程中,发送方使用AES算法和特定的密钥对数据进行加密,同时加入时间戳以增加数据的新鲜度。接收方收到加密数据后,使用相同的密钥进行AES解密,并验证时间戳以确保数据的完整性和有效性。

然而,这种加密方式需要跳转方和被跳转方维护相同的AES密钥,这增加了密钥泄露的风险和管理成本。为了解决这一问题,我们设计了一种基于随机数密文和IP验证的加密方式。该方式通过生成随机的密文,并结合IP地址验证,确保了数据的安全性和可追溯性。

请参见以下架构图,以更直观地了解这一加密方式的工作原理:

image-20240204162422004

这种加密方式的流程为:

  1. 当APP产生跳转需求时,向后端服务器发送请求。后端服务器在接收请求后,会组装相关数据,并生成一个随机数作为密文。为了确保数据的安全性,后端会将密文与数据之间的关系存储在内存或数据库中,并记录当前的时间戳。
  2. 随机数密文被传递给前端。前端接收到密文后,会根据密文拼装出跳转的URL Scheme或Universal Link,然后进行跳转。
  3. 当用户手机上已经安装了相应的APP时,被跳转的APP会被唤醒。在APP被唤醒后,它会获取到密文,并调用后端接口,根据密文来获取对应的数据。
  4. 后端服务器在接收到解密请求后,会验证调用方的IP地址。同时,还会验证密文生成的时间戳。如果调用方的IP地址和时间戳验证通过,后端服务器将允许解析该密文,并将对应的数据返回给调用方。反之,如果调用时间超出密文生成时间过久,后端服务器将不允许解析该密文,以防止数据被篡改或泄露。

通过这种方式,我们可以在保证数据安全的同时,降低密钥管理的风险和成本。同时这种安全性也更高,增加了IP验证后只有受认可的被跳转方才能对密文进行解密,从而获取到用户信息。

实现方式

环境

  • React Native
  • JavaScript

APP跳转

React Native 提供了一种方便的方式来实现在不同APP之间进行跳转。通过使用 Linking 模块,我们可以将拼接好的 URL Scheme 或 Universal Link 传递给目标APP,从而进行跳转。

值得注意的是,Linking 的返回值还定义了当目标APP未安装时的 code。这意味着我们可以根据这个 code 来判断用户是否已经安装了目标APP,并在必要时执行相应的回调操作。这为用户提供了更加流畅和个性化的体验,并有助于提升用户对应用的满意度。

import { Linking } from 'react-native';

async function jumpToApp() {
  const url = 'your_app_universal_link';
  Linking.openURL(url).catch(err => {
            if (err.code === 'EUNSPECIFIED') {
                //用户未安装APP时的处理
            } else {
                //其他错误的处理
            }
        });
}
最后修改日期: 2024年2月4日

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。