如何验证REST API请求仅来自我方React Native移动应用?
验证React Native应用API请求来源的可行方案
要确保API请求仅来自你的合法应用,核心思路是增加攻击成本(客户端代码无法做到绝对防篡改),结合以下几种方案组合使用效果最佳:
1. 平台原生应用签名验证
针对Android和iOS分别做应用合法性校验:
- Android:
运行时获取应用的签名哈希值(避免硬编码),请求时将哈希值(可结合时间戳、请求路径做二次签名)放在自定义请求头(如X-App-Signature)。服务器预存你应用的合法签名哈希,收到请求后对比校验,同时校验时间戳有效期(比如5分钟)防止重放攻击。
获取签名哈希的核心逻辑(Android原生代码,可通过RN桥接调用):// 获取应用签名哈希示例 PackageInfo packageInfo = getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES); Signature[] signatures = packageInfo.signatures; MessageDigest md = MessageDigest.getInstance("SHA-256"); md.update(signatures[0].toByteArray()); String signatureHash = Base64.encodeToString(md.digest(), Base64.DEFAULT); - iOS:
同样运行时获取应用的Bundle ID和签名证书信息,生成唯一标识后传给服务器。服务器预存你应用的合法Bundle ID和签名指纹,请求时校验匹配性。
2. 利用官方平台验证服务
借助Apple和Google提供的官方服务,直接验证应用合法性:
- iOS App Attest:
客户端向Apple请求生成验证凭证,将凭证随API请求发送给服务器。服务器调用Apple的App Attest验证接口,确认凭证有效且来自你的已签名应用。 - Android SafetyNet Attestation:
客户端调用Google SafetyNet API获取Attestation Token,服务器将Token发送给Google验证接口,确认应用未被篡改、运行在合法的Android环境(非模拟器/越狱设备)。
这类方案安全性最高,但需要依赖平台服务,要处理网络异常和调用限额问题。
3. 请求签名机制
客户端和服务器共享动态短期密钥(禁止硬编码在客户端,可通过用户登录后从服务器获取),每次请求时对请求参数、时间戳、API路径做HMAC签名:
- 客户端伪代码(RN):
import crypto from 'react-native-crypto'; // 生成请求签名 const generateRequestSignature = (params, timestamp, secret, apiPath) => { // 按参数名排序,避免顺序影响签名结果 const sortedParams = Object.keys(params).sort().map(key => `${key}=${params[key]}`).join('&'); const signStr = `${timestamp}&${apiPath}&${sortedParams}`; return crypto.createHmac('sha256', secret).update(signStr).digest('hex'); }; // 发起请求时添加签名头 const requestHeaders = { 'Authorization': `Bearer ${userAuthToken}`, 'X-Request-Sign': generateRequestSignature(requestParams, Date.now(), sessionSecret, '/api/user/profile'), 'X-Request-Timestamp': Date.now().toString() }; - 服务器端校验:
- 先校验用户认证令牌的有效性
- 取出请求头的时间戳,检查是否在有效期内(比如5分钟)
- 用相同的规则生成签名,对比请求头的签名是否一致
4. 辅助校验手段
- User-Agent过滤:设置自定义的User-Agent(比如
MyApp/1.0.0 (com.mycompany.myapp)),服务器只接受包含该标识的请求。注意:User-Agent容易伪造,仅作为辅助验证。 - 环境校验:客户端检查是否运行在越狱/root设备、模拟器中,这类环境下的请求直接拦截(或标记后服务器重点校验)。
关键注意事项
- 没有绝对的安全:任何客户端逻辑都可能被逆向分析,以上方案都是提高攻击门槛,建议组合多种方案使用(比如用户令牌+App Attest+请求签名)。
- 密钥轮换:如果使用共享密钥,定期更新密钥,降低泄露风险。
- 避免硬编码敏感信息:所有签名密钥、哈希值都不要直接写在代码里,尽量通过运行时获取或动态请求。
内容的提问来源于stack exchange,提问作者avinash buddana
相关产品推荐
相关产品推荐

