iOS Swift 5/Xcode 12使用URLSession实现Basic auth认证失败如何解决
问题根因排查
你遇到的错误码-9816属于苹果安全框架的SSL/TLS连接层错误,和你编写的Basic Auth头设置逻辑无关——当前网络连接尚未成功建立,还未到传递认证头的请求阶段。你可以按以下顺序排查连接问题:
- 第一步:确认请求URL的协议类型,若为
http协议,iOS 9及以上版本默认ATS(应用传输安全)会拦截未加密的HTTP请求,需在Info.plist中添加对应域名的ATS例外配置,或者临时开启全局HTTP允许(不推荐生产环境使用)。 - 第二步:若请求为
https协议,检查服务端SSL证书是否为自签名证书、TLS版本是否低于1.2,不符合ATS默认要求的SSL配置都会触发连接报错,可根据场景配置对应ATS例外,或者在URLSession代理中处理自签名证书的信任逻辑。 - 第三步:确认服务端接口是否正常可用,可先用接口调试工具模拟带Basic Auth头的请求,验证接口返回是否正常。
正确的Basic Auth实现方案
你当前的认证头写法本身是符合规范的,以下为完整可运行的实现示例:
guard let mhURL = URL(string: "你的接口地址") else { return } var request = URLRequest(url: mhURL) // 根据接口要求调整请求方法,常见为GET/POST request.httpMethod = "GET" // 生成Basic Auth头 let username = "你的用户名" let password = "你的密码" let loginString = "\(username):\(password)" guard let loginData = loginString.data(using: .utf8) else { return } let base64LoginString = loginData.base64EncodedString() request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization") // 发起请求 let task = URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { print("请求错误: \(error)") return } // 处理响应数据 if let data = data, let result = String(data: data, encoding: .utf8) { print("响应结果: \(result)") } } task.resume()
如果服务端采用401质询的认证逻辑,也可以通过URLSession代理处理认证挑战,写法更规范:
// 实现URLSessionDelegate的didReceiveChallenge方法 func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPBasic { let credential = URLCredential(user: "用户名", password: "密码", persistence: .forSession) completionHandler(.useCredential, credential) } else { completionHandler(.performDefaultHandling, nil) } }
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

