如何使用 Alamofire 连接本地主机(证书无效)?
How to Connect localhost (with invalid certificate) using Alamofire?
这是我使用 swift 的第一个项目。我正在使用 alamofire 连接 API。我有一个 API 的本地副本,我想用于调试 - 所以我可以设置测试数据 - 因为远程 API 已经有了我不能乱用的真实数据。
问题是当我尝试访问 https://localhost:8443/MyProject
时出现以下错误
Optional(Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “localhost” which could put your confidential information at risk." UserInfo=0x7fbeb8c61ff0 {NSURLErrorFailingURLPeerTrustErrorKey=, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorCodeKey=-9813, NSUnderlyingError=0x7fbeb8ea5c00 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1202.)", NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “localhost” which could put your confidential information at risk., NSErrorFailingURLKey=https://localhost:8443/myproject/api/loginUser.pdo, NSErrorFailingURLStringKey=https://localhost:8443/myproject/api/loginUser.pdo, _kCFStreamErrorDomainKey=3})
我已经找到了很多解决方案,其中大部分是针对 Objective-c 的,例如使用 setAllowsAnyHTTPSCertificate
或使用委托进行连接。
但是我在 swift 中找不到 setAllowsAnyHTTPSCertificate
的等价方法,而且我不确定在使用 alamofire 时如何将委托设置为连接。
我有什么想法吗?
- 我知道
setAllowsAnyHTTPSCertificate
是私有的 api 并且会导致该项目被 Apple 拒绝。我只想在调试时使用它,然后在发布项目之前将其删除。
提前致谢。
您可以使用 SessionDelegate
覆盖闭包轻松覆盖 Alamofire 中的默认质询行为。以下是如何允许 Alamofire 接受无效证书的示例:
IMPORTANT: Please do not use this in any production code. Security is VERY important and this implementation completely disregards the security mechanisms in Alamofire. Use at your own risk!
let manager = Alamofire.Manager.sharedInstance
manager.delegate.sessionDidReceiveChallenge = { session, challenge in
var disposition: NSURLSessionAuthChallengeDisposition = .PerformDefaultHandling
var credential: NSURLCredential?
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
disposition = NSURLSessionAuthChallengeDisposition.UseCredential
credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust)
} else {
if challenge.previousFailureCount > 0 {
disposition = .CancelAuthenticationChallenge
} else {
credential = manager.session.configuration.URLCredentialStorage?.defaultCredentialForProtectionSpace(challenge.protectionSpace)
if credential != nil {
disposition = .UseCredential
}
}
}
return (disposition, credential)
}
我们(Alamofire TC) are going to implement TLS pinning and several other features related to security in the Alamofire 1.3.0发布。
更新
Alamofire 1.3.0 版本已经发布,并为自定义服务器信任身份验证挑战添加了更好的支持。有关详细信息,请查看自述文件的 Security 部分。
Swift @cnoon 代码的 3 版本
manager.delegate.sessionDidReceiveChallenge = { session, challenge in
var disposition: URLSession.AuthChallengeDisposition = .performDefaultHandling
var credential: URLCredential?
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust, let trust = challenge.protectionSpace.serverTrust {
disposition = URLSession.AuthChallengeDisposition.useCredential
credential = URLCredential(trust: trust)
} else {
if challenge.previousFailureCount > 0 {
disposition = .cancelAuthenticationChallenge
} else {
credential = self.manager.session.configuration.urlCredentialStorage?.defaultCredential(for: challenge.protectionSpace)
if credential != nil {
disposition = .useCredential
}
}
}
return (disposition, credential)
}
将 https 替换为我的基地 url 的 http。解决了错误。
Swift 3
就我而言,当我使用 swagger 客户端库时,我更改了代码以像这样测试本地服务器:
open func createSessionManager() -> Alamofire.SessionManager {
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = buildHeaders()
let serverTrustPolicies: [String: ServerTrustPolicy] = ["localhost": .disableEvaluation]
return Alamofire.SessionManager(configuration: configuration, serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies))
}
这是我使用 swift 的第一个项目。我正在使用 alamofire 连接 API。我有一个 API 的本地副本,我想用于调试 - 所以我可以设置测试数据 - 因为远程 API 已经有了我不能乱用的真实数据。
问题是当我尝试访问 https://localhost:8443/MyProject
Optional(Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “localhost” which could put your confidential information at risk." UserInfo=0x7fbeb8c61ff0 {NSURLErrorFailingURLPeerTrustErrorKey=, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorCodeKey=-9813, NSUnderlyingError=0x7fbeb8ea5c00 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1202.)", NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “localhost” which could put your confidential information at risk., NSErrorFailingURLKey=https://localhost:8443/myproject/api/loginUser.pdo, NSErrorFailingURLStringKey=https://localhost:8443/myproject/api/loginUser.pdo, _kCFStreamErrorDomainKey=3})
我已经找到了很多解决方案,其中大部分是针对 Objective-c 的,例如使用 setAllowsAnyHTTPSCertificate
或使用委托进行连接。
但是我在 swift 中找不到 setAllowsAnyHTTPSCertificate
的等价方法,而且我不确定在使用 alamofire 时如何将委托设置为连接。
我有什么想法吗?
- 我知道
setAllowsAnyHTTPSCertificate
是私有的 api 并且会导致该项目被 Apple 拒绝。我只想在调试时使用它,然后在发布项目之前将其删除。
提前致谢。
您可以使用 SessionDelegate
覆盖闭包轻松覆盖 Alamofire 中的默认质询行为。以下是如何允许 Alamofire 接受无效证书的示例:
IMPORTANT: Please do not use this in any production code. Security is VERY important and this implementation completely disregards the security mechanisms in Alamofire. Use at your own risk!
let manager = Alamofire.Manager.sharedInstance
manager.delegate.sessionDidReceiveChallenge = { session, challenge in
var disposition: NSURLSessionAuthChallengeDisposition = .PerformDefaultHandling
var credential: NSURLCredential?
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
disposition = NSURLSessionAuthChallengeDisposition.UseCredential
credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust)
} else {
if challenge.previousFailureCount > 0 {
disposition = .CancelAuthenticationChallenge
} else {
credential = manager.session.configuration.URLCredentialStorage?.defaultCredentialForProtectionSpace(challenge.protectionSpace)
if credential != nil {
disposition = .UseCredential
}
}
}
return (disposition, credential)
}
我们(Alamofire TC) are going to implement TLS pinning and several other features related to security in the Alamofire 1.3.0发布。
更新
Alamofire 1.3.0 版本已经发布,并为自定义服务器信任身份验证挑战添加了更好的支持。有关详细信息,请查看自述文件的 Security 部分。
Swift @cnoon 代码的 3 版本
manager.delegate.sessionDidReceiveChallenge = { session, challenge in
var disposition: URLSession.AuthChallengeDisposition = .performDefaultHandling
var credential: URLCredential?
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust, let trust = challenge.protectionSpace.serverTrust {
disposition = URLSession.AuthChallengeDisposition.useCredential
credential = URLCredential(trust: trust)
} else {
if challenge.previousFailureCount > 0 {
disposition = .cancelAuthenticationChallenge
} else {
credential = self.manager.session.configuration.urlCredentialStorage?.defaultCredential(for: challenge.protectionSpace)
if credential != nil {
disposition = .useCredential
}
}
}
return (disposition, credential)
}
将 https 替换为我的基地 url 的 http。解决了错误。
Swift 3
就我而言,当我使用 swagger 客户端库时,我更改了代码以像这样测试本地服务器:
open func createSessionManager() -> Alamofire.SessionManager {
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = buildHeaders()
let serverTrustPolicies: [String: ServerTrustPolicy] = ["localhost": .disableEvaluation]
return Alamofire.SessionManager(configuration: configuration, serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies))
}