iOS测试环境下信任REST API服务器自签名证书的方法
iOS测试环境信任自签名REST API证书的解决办法
测试环境专用方案
1. 针对特定域名放宽ATS限制(推荐)
比起全局禁用ATS,只给测试服务器域名开例外更安全,也符合苹果规范。在项目的Info.plist中添加以下配置:
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>你的测试服务器域名(如test-api.local)</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSExceptionAllowsInsecureHTTPLoads</key> <false/> <!-- 保持HTTPS,仅信任指定自签名证书 --> <key>NSExceptionRequiresForwardSecrecy</key> <false/> <key>NSExceptionMinimumTLSVersion</key> <string>TLSv1.2</string> </dict> </dict> </dict>
同时将自签名证书的.cer文件拖进Xcode项目,勾选你的应用目标,确保证书被打包进App。
2. 全局禁用ATS(仅紧急测试用)
如果只是临时快速测试,可以全局关闭ATS,但绝对不能用于生产包。在Info.plist中添加:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
3. 自定义URLSession证书验证
通过代码手动验证自签名证书,避免全局放宽限制。实现URLSessionDelegate的代理方法:
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { guard let serverTrust = challenge.protectionSpace.serverTrust else { completionHandler(.cancelAuthenticationChallenge, nil) return } // 严谨场景可提前硬编码证书公钥/指纹,在此处对比验证,防止信任未知证书 let credential = URLCredential(trust: serverTrust) completionHandler(.useCredential, credential) }
变通调试方案
使用抓包工具(如Charles)作为中间代理:
- 在iOS设备上安装Charles的根证书并信任
- 配置App的网络请求走Charles代理
- 让Charles转发请求到测试服务器,此时App会信任Charles的证书,间接实现正常连接
该方案适合同时需要调试请求内容的场景。
注意事项
- 所有测试环境方案严禁用于生产,生产必须使用受信任CA签发的证书
- iOS 13+之后,苹果对ATS限制更严格,全局禁用ATS的包提交App Store会被拒绝
- 不要使用完全忽略证书验证的代码(如直接信任所有证书),即使测试环境也存在安全风险
内容的提问来源于stack exchange,提问作者SeattleOrBayArea
相关产品推荐
相关产品推荐

