如何在URLSession中使用URLCredential实现非基础认证
在Swift中用URLSession结合URLCredential实现非基础认证的用户名密码验证
要实现非基础认证的用户名密码验证,你不能直接用URLSession.shared——它的代理是系统内部的,没法自定义。得自己创建URLSession并设置代理,处理服务器抛出的认证挑战,具体步骤如下:
1. 自定义URLSession并实现代理
先让你的类遵循URLSessionDelegate协议,创建带代理的URLSession实例:
class YourNetworkHandler: URLSessionDelegate { private var customSession: URLSession! init() { let config = URLSessionConfiguration.default // 初始化自定义Session,绑定当前类为代理,代理队列用主队列(也可以用后台队列,根据需求调整) customSession = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main) } }
2. 实现认证挑战处理方法
在代理类里实现urlSession(_:didReceive:completionHandler:)方法,这是处理认证请求的核心:
extension YourNetworkHandler { func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { let protectionSpace = challenge.protectionSpace // 跳过服务器信任认证(比如HTTPS证书验证,交给系统默认处理) if protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { completionHandler(.performDefaultHandling, nil) return } // 处理用户名密码类型的认证(支持Digest等非基础认证) let username = "你的用户名" let password = "你的密码" // 创建凭证:persistence选.forSession表示仅当前会话有效,也可选.permanent(存钥匙串)或.none let credential = URLCredential(user: username, password: password, persistence: .forSession) // 告诉Session使用这个凭证完成认证 completionHandler(.useCredential, credential) } }
3. 修改请求代码使用自定义Session
把你原来的startLoad方法放到代理类里,替换成自定义的Session发起请求:
extension YourNetworkHandler { func startLoad() { guard let url = URL(string: "https://www.abcde-test-url.com/") else { print("无效URL") return } let task = customSession.dataTask(with: url) { data, response, error in if let error = error { print("客户端错误: \(error.localizedDescription) \n") return } guard let data = data, let httpResponse = response as? HTTPURLResponse else { print("无数据或无响应") return } if httpResponse.statusCode == 200 { print("请求成功,返回数据: \(data)") } else { print("错误状态码: \(httpResponse.statusCode)\n") } } task.resume() } }
使用示例
在需要发起请求的地方,初始化这个网络处理类并调用方法:
let handler = YourNetworkHandler() handler.startLoad()
关键说明
- 不管是Digest还是其他非基础的用户名密码认证,URLSession都会自动处理对应的认证流程,你只需要提供正确的凭证即可,不用手动构造认证头。
- 凭证的
persistence参数可根据需求调整:.forSession仅当前App会话有效,.permanent会保存到系统钥匙串,.none则不保存。 - 如果服务器同时要求HTTPS证书验证,上面的代码已经跳过了这部分(交给系统默认处理),如果需要自定义证书验证,可以在
NSURLAuthenticationMethodServerTrust分支里添加逻辑。
内容的提问来源于stack exchange,提问作者Keita Sumiya
相关产品推荐
相关产品推荐

