You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS网络模块实现URLSessionDelegate绕过证书验证失败求助

iOS框架绕过证书验证失败问题

问题详情

我做了一个作为网络模块的iOS框架,要绕过证书验证,但网上找的基于URLSessionDelegate的方案都没用。

当前代码

extension FCSession: URLSessionDelegate {
    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        
        switch challenge.protectionSpace.authenticationMethod {
        case NSURLAuthenticationMethodServerTrust:
            if let serverTrust = challenge.protectionSpace.serverTrust {
                let credential = URLCredential(trust: serverTrust)
                
                completionHandler(.useCredential, credential)
            }
        default:
            completionHandler(.rejectProtectionSpace, nil)
        }
    }
}

报错信息

Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, NSErrorPeerCertificateChainKey=(
"<cert(0x10880ac00)

已尝试操作

直接把serverTrust传入completionHandler,还是报同样的错:

completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))

解决办法

1. 确认URLSession绑定了正确的Delegate

不能用默认的URLSession.shared,必须手动初始化会话并指定delegate为FCSession实例:

let config = URLSessionConfiguration.default
let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)

如果会话没绑定Delegate,自定义的证书验证方法根本不会触发。

2. 显式标记服务器信任有效

只返回URLCredential可能不够,需要手动设置信任锚点:

extension FCSession: URLSessionDelegate {
    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust,
              let serverTrust = challenge.protectionSpace.serverTrust else {
            completionHandler(.performDefaultHandling, nil)
            return
        }
        
        // 允许信任任意证书
        SecTrustSetAnchorCertificates(serverTrust, [])
        SecTrustSetAnchorCertificatesOnly(serverTrust, false)
        
        let credential = URLCredential(trust: serverTrust)
        completionHandler(.useCredential, credential)
    }
}

3. 配置ATS例外

在项目的Info.plist里添加ATS配置,允许非安全连接:

<key>NSAppTransportSecurity</key>
<dict>
    <!-- 全局允许(仅测试用,上线建议用特定域名例外) -->
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <!-- 特定域名例外(更安全) -->
    <!--
    <key>NSExceptionDomains</key>
    <dict>
        <key>你的服务器域名.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
    -->
</dict>

4. 验证Delegate方法是否触发

在证书验证方法里加个打印,确认方法是否被调用:

print("证书验证方法已触发")

如果没打印,说明会话的Delegate没设置对,或者请求用了其他会话实例。


内容的提问来源于stack exchange,提问作者Filipe Marques

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 07:55:26