• 2026年7月20日
  • 5 分钟阅读
  • SystemDo

uni-app 跨端应用安全怎么做?本地存储、通信与隐私权限

uni-app 跨端应用的安全设计集中在本地存储加密、通信保护、权限最小化和隐私合规。本文从工程实践出发,分析敏感数据隔离、证书固定、日志脱敏和合规审核等关键问题,帮助团队在开发阶段建立可落地的安全基线。

uni-app 跨端应用安全怎么做?本地存储、通信与隐私权限
SystemDo
SystemDo

软件定制开发团队

"真正有价值的技术内容,应该能帮助客户更快判断方向、预算和落地路径。"

跨端安全不是可选项,是默认需求

uni-app 的跨端特性让团队能用一套代码同时输出 iOS、Android、H5 和各平台小程序,但这也意味着安全设计必须覆盖多个运行时环境。很多团队在初期只关注业务功能,等到应用上线后才发现:本地存储的 Token 被其他应用读取、HTTPS 证书校验被中间人绕过、权限申请弹窗被用户拒绝后功能异常、日志中明文记录了用户手机号。

这些问题在单一平台开发中已经需要重视,在跨端场景下更复杂——每个平台对存储隔离、网络栈、权限模型和隐私合规的要求都不同。本文从本地存储、通信保护、权限管理和隐私合规四个维度展开,只讨论工程中能直接落地的做法。

本地存储:不同数据的隔离与加密策略

区分三类敏感数据

在 uni-app 中,所有通过 `uni.setStorageSync` 写入的数据都存放在各平台默认的本地存储区域。但不同平台对这块区域的保护力度差异很大:

  • iOS:`NSUserDefaults` 默认不加密,且不进行文件级保护。如果设备已越狱,其他应用或攻击者可以直接读取。
  • Android:`SharedPreferences` 存储在 `/data/data/<package>/shared_prefs/` 下,未 Root 设备上其他应用无法直接访问,但 Root 设备上无保护。
  • 小程序:数据存储在微信或支付宝的沙箱内,外部应用无法直接读取,但小程序管理后台或第三方插件可能通过接口获取部分数据。

因此,不能把“平台默认安全”当作安全策略。必须对数据分级处理:

  • 低敏感数据:如用户偏好设置、主题颜色、界面布局缓存。可以使用 `uni.setStorageSync`,无需额外加密。
  • 中敏感数据:如用户昵称、头像 URL、设备标识。建议在写入前用 AES-256-GCM 加密,密钥由服务端下发或通过 Keychain(iOS)/ Keystore(Android)存储。
  • 高敏感数据:如登录 Token、支付密钥、身份证号。不应长期存于本地存储,应使用平台级安全存储。iOS 用 Keychain,Android 用 EncryptedSharedPreferences 或 Keystore。uni-app 没有原生封装,需要通过插件或原生模块桥接。

实际做法:用插件桥接原生安全存储

我们曾在项目中遇到一个典型问题:Token 存储在 `uni.setStorageSync` 中,测试时发现 Android 设备上通过 adb 备份可以导出所有 SharedPreferences 文件。解决方案是为 Android 端集成了 `androidx.security.crypto.EncryptedSharedPreferences`,iOS 端使用 Keychain 存储。uni-app 端通过自定义插件暴露 `setSecureStorage(key, value)` 和 `getSecureStorage(key)` 两个接口。

需要注意,跨端条件下无法保证所有平台都有等价的加密存储能力。小程序端无法使用原生 Keychain,所以高敏感数据在小程序中应改为每次从服务端获取,不在本地持久化。

存储数据的最小化原则

一个常见错误是把整个用户对象(包含手机号、身份证、地址)一次性存到本地。正确的做法是只存储业务必须的标识和 Token,其他数据通过接口按需获取。这样即使本地存储被攻破,泄露的信息也有限。

通信安全:证书固定与防中间人

HTTPS 是基础,但不是全部

大多数 uni-app 应用使用 `uni.request` 发起网络请求,默认走 HTTPS。但默认的 HTTPS 只验证系统根证书链,如果设备安装了恶意根证书(例如企业代理、抓包工具),中间人攻击依然有效。对于金融、支付或涉及用户敏感数据的场景,必须实施证书固定(Certificate Pinning)。

在 uni-app 中实现证书固定

uni-app 的 `uni.request` 不直接支持证书固定。通用做法有两种:

  • 使用原生插件:在 iOS 端通过 `URLSession` 的 `URLSessionDelegate` 实现证书校验,Android 端通过 `OkHttp` 的 `CertificatePinner`。需要开发原生插件或使用社区方案。
  • 使用 WebView 拦截:如果应用以 WebView 为主,可以在 WebView 层面注入 SSL 校验逻辑。但这种方式对原生请求无效。

我们在一款金融类 APP 中采用了第一种方案:后端提供证书公钥的 SHA-256 指纹,原生插件在连接建立时校验服务端证书指纹是否匹配。如果指纹不匹配,直接断开连接并返回错误码。uni-app 端只需调用一个 `setSSLPinning(fingerprint)` 方法,出错时提示用户网络不安全。

需要注意,证书有有效期,指纹更新需要与应用版本同步,否则会导致用户无法正常使用。建议在服务端保留至少两个有效的证书指纹,并在应用内预置一组备用指纹,通过接口动态更新。

请求参数与响应数据的加密

即使使用 HTTPS,请求参数和响应数据在应用内存中仍然是明文。如果应用被 Hook 或动态调试,攻击者可以读取这些数据。对于高度敏感的场景(如支付签名、用户密码),建议在应用层再做一层加密:

  • 使用 AES 对称加密,密钥由服务端通过非对称加密传递。
  • 每次请求生成随机 IV,加密后传输,服务端解密后处理。
  • 响应数据同样加密,应用端解密后使用。

这层加密会增加开发和调试成本,只建议在涉及资金、个人敏感信息或核心业务逻辑的接口上使用。

权限申请:最小化与时机控制

不同平台的权限模型差异

uni-app 封装了 `uni.authorize`、`uni.getLocation` 等 API,但底层权限模型各平台不同:

  • iOS:权限申请必须在 Info.plist 中声明用途描述,首次使用时弹窗询问。用户拒绝后,系统不会再次弹窗,只能引导用户去设置中开启。
  • Android:从 Android 6.0 开始运行时权限,用户可随时关闭。Android 11 之后,如果用户多次拒绝,系统会不再弹窗,直接返回拒绝。
  • 微信小程序:权限由微信统一管理,开发者只能通过 `wx.authorize` 申请,用户拒绝后无法再次弹窗,需要引导用户手动开启。

最佳实践:按需申请,提前说明

不要在一开始就申请所有权限。正确的做法是:

1. 在用户触发需要权限的功能时,先通过弹窗说明为什么需要这个权限,例如“我们需要访问您的位置以显示附近的商家”。
2. 用户确认后,再调用 `uni.authorize` 或对应平台 API。
3. 如果用户拒绝,不要反复弹窗。记录拒绝状态,在用户再次使用该功能时,提供“前往设置”的引导按钮。

在 uni-app 中,可以通过 `uni.getSetting` 检查权限状态,判断是“未申请”“已授权”还是“已拒绝”。根据状态决定下一步行为。

权限申请中的隐私合规问题

国内各应用商店(尤其是苹果 App Store 和华为应用市场)对权限申请有严格审核。常见违规行为包括:

  • 申请与业务无关的权限,如计算器应用申请通讯录权限。
  • 未在隐私政策中说明权限用途。
  • 用户拒绝权限后,应用直接闪退或无法使用核心功能。

在 uni-app 项目中,建议在开发阶段就维护一份权限清单,列出每个权限对应的业务场景和用途,并在隐私政策中明确说明。上线前使用各平台的合规检测工具(如腾讯的隐私合规检测)进行扫描。

日志与调试信息:最容易忽视的数据泄露渠道

生产环境必须关闭日志输出

开发阶段,`console.log` 是调试利器,但很多团队在发布时忘记移除或关闭日志输出。这些日志如果包含用户数据、Token、接口返回信息,一旦被攻击者通过日志收集工具(如 Android 的 logcat)读取,就是直接的数据泄露。

uni-app 项目可以通过以下方式控制日志:

  • 在 `manifest.json` 中配置 `debug` 模式,生产环境设为 `false`。
  • 在代码中封装日志工具,根据环境变量决定是否输出。
  • 使用 `__DEV__` 或 `process.env.NODE_ENV` 判断环境,只在开发环境打印日志。

错误上报中的敏感数据过滤

很多应用集成了错误监控 SDK(如 Sentry、Bugly),这些 SDK 默认会上报错误堆栈和应用状态。如果错误发生时,堆栈中包含了用户输入或接口返回数据,这些数据会随错误信息一起上传到第三方服务器。

建议在初始化错误监控 SDK 时,配置数据过滤规则。例如,过滤掉所有包含 `password`、`token`、`phone` 字段的变量值。uni-app 中可以通过插件或自定义上报逻辑实现。

隐私合规:跨端场景的额外挑战

各平台隐私政策要求

不同平台对隐私政策的展示方式和内容要求不同:

  • iOS:必须提供隐私政策链接,且应用首次启动时通过弹窗展示摘要。
  • Android:Google Play 要求应用内显示隐私政策,国内应用市场也有类似要求。
  • 微信小程序:必须在 app.json 中配置隐私政策页面路径,用户首次进入时弹窗确认。

uni-app 项目需要为每个平台单独配置隐私政策的展示逻辑。建议在应用启动时统一检测,如果用户未同意隐私政策,阻止所有数据收集和网络请求。

数据跨境传输声明

如果应用使用了海外云服务(如 AWS、Google Cloud),或者用户数据会传输到境外服务器,必须在隐私政策中明确说明,并获得用户同意。这点在跨端应用中容易被忽略,尤其是 H5 版本通过 CDN 加载资源时,用户 IP 可能被 CDN 服务商记录。

合规审核中的常见问题

我们曾协助一个客户处理应用商店审核被拒的问题,原因是应用在用户未同意隐私政策前就调用了 `uni.getSystemInfo` 获取设备信息。解决方案是在应用启动时先展示隐私政策弹窗,用户同意后再初始化 SDK 和获取设备信息。这个改动看似简单,但需要从代码架构层面调整初始化顺序。

安全测试:上线前的必要检查

静态分析与动态测试

在 uni-app 项目中,建议在上线前进行以下检查:

  • 静态扫描:使用工具(如 MobSF)扫描 APK/IPA 文件,检查是否存在硬编码密钥、未加密的本地存储、未关闭的调试模式。
  • 动态测试:使用抓包工具(如 Charles、Burp Suite)验证 HTTPS 证书固定是否生效,检查请求和响应中是否包含明文敏感数据。
  • 权限测试:在 iOS 和 Android 设备上分别测试权限拒绝场景,确保应用不会崩溃或功能异常。

自动化安全流水线

对于持续迭代的项目,可以将安全检查集成到 CI/CD 流程中。例如,每次构建后自动运行 MobSF 扫描,如果发现高风险问题则阻止发布。这项工作需要一定的配置成本,但对于企业级应用来说值得投入。

总结:安全设计要前置,跨端要逐个平台验证

uni-app 跨端应用的安全设计不是简单套用一套方案就能覆盖所有平台。每类数据(本地存储、通信、权限、日志)都需要针对不同平台的特性做差异化处理。核心原则只有三条:最小化数据存储、加密敏感信息、按需申请权限。在开发阶段就把这些策略写进代码,比上线后发现问题再修复的成本低得多。

在 SystemDo 的多个跨端项目中,我们总结的经验是:安全设计从架构阶段开始,每个平台独立验证,同时保持代码层面的统一接口。这样既能保证安全效果,也能维持开发效率。