如何使用Swift实现仅允许App Store安装的iOS应用调用后端API
实现方案
客户端(Swift)逻辑
- 核心通过App Store专属收据路径判断安装来源,非App Store渠道(Xcode调试、TestFlight、企业签名、越狱安装)的收据属性会存在明显差异,参考实现代码:
func isOfficialAppStoreInstall() -> Bool { // 无收据直接判定为非官方渠道 guard let receiptUrl = Bundle.main.appStoreReceiptURL else { return false } // 排除TestFlight沙箱测试环境 if receiptUrl.lastPathComponent == "sandboxReceipt" { return false } // 排除本地Xcode调试安装场景 #if DEBUG return false #endif return FileManager.default.fileExists(atPath: receiptUrl.path) }
- 注意:客户端本地校验逻辑可被逆向篡改,不可单独作为接口权限判断依据,必须搭配后端二次校验使用
后端(PHP)二次校验逻辑
- 客户端调用接口时,需将读取到的收据文件原始数据做Base64编码,和业务参数一同提交到后端
- 后端将Base64格式的收据数据提交到苹果官方校验接口完成合法性校验:
- 生产环境校验接口地址:
https://buy.itunes.apple.com/verifyReceipt - 沙箱环境校验接口地址:
https://sandbox.itunes.apple.com/verifyReceipt
- 生产环境校验接口地址:
- 校验规则:
- 接口返回
status字段值为0代表收据本身合法 - 校验返回结果内的
bundle_id和你的应用包名完全一致,防止其他应用盗用合法收据 - 确认返回结果无
sandbox属性标识,排除TestFlight环境安装的应用
- 接口返回
- 校验通过后再放行业务请求,否则直接返回权限错误
安全加固建议
- 所有接口请求增加约定规则的签名校验,防止请求参数被篡改
- 合法的收据校验结果可在后端缓存3-7天,无需每次请求都调用苹果接口,减少请求耗时
- 对多次提交无效收据的IP或设备做限流封禁,降低恶意攻击风险
内容的提问来源于stack exchange,提问作者Mohamed Ali
相关产品推荐
相关产品推荐

