Swift - WebView HTTP Auth - 最干净的解决方案
Swift - WebView HTTP Auth - Cleanest solution
我一直在尝试设置一个 web view wrapper 应用程序来加载网站的内容(仍待启动)。目前,该网站处于开发模式,该网站的唯一端点受 http 身份验证保护。
我一直在看这个解决方案:
但是,我不想每次都发出 POST 请求,但我宁愿对网站进行一次身份验证并保持连接。
我正在寻找一个干净稳定的解决方案,一个可以让我能够控制边缘情况的解决方案,例如提供的错误凭据。
我不习惯使用 NSURLConnection,因为该解决方案在 iOS9 中已被弃用。我需要一个 NSURLSession 的解决方案。
如果我在上述链接的解决方案中遗漏了某些内容,请告诉我。我相信也有人遇到过这个问题。此外,该网站具有 SSL 保护。
亲切的问候
您不需要使用 POST 或连接或 session。您应该只创建一个可变 URL 请求并设置一个身份验证 header。然后要求网页视图加载请求。
Auth header 来自维基百科的详细信息:
- 用户名和密码由一个冒号组合而成。
- 生成的字符串使用 Base64 的 RFC2045-MIME 变体编码,但不限于 76 char/line。
- 然后将授权方法和 space 即 "Basic " 放在编码字符串之前。
例如,如果用户代理使用 Aladdin 作为用户名,使用 OpenSesame 作为密码,则该字段构成如下:
Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l
我不完全确定这是否能以最佳方式满足您的需求,但如果您可以使用 WKWebView
,也许您可以简单地依赖身份验证质询委托方法?也请参阅我的回答 here,相关代码片段为:
func webView(webView: WKWebView, didReceiveAuthenticationChallenge
challenge: NSURLAuthenticationChallenge,
completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
let creds = NSURLCredential(user:"username", password:"password", persistence: NSURLCredentialPersistence.ForSession)
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, creds)
}
我自己还没有尝试过,但文档说凭据应该用于 session,因此链接产生的其他请求应该有效。即使没有,也只会导致再次调用该方法,您可以再次提供凭据。
这只是个小问题,您必须从警报等中获取名称和密码(您也可以更优雅地存储凭据,以便后续调用委托方法更优雅)。
您还写道您正在使用 SSL,所以我认为您熟悉 App Transport Security 标志(因为问题标题中只有 "HTTP" 而不是 "HTTPS",您可能希望它顺利运行,否则请参阅我链接的问题)。
好的,这是 Swift 3 代码。
extension MyController: WKNavigationDelegate {
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
guard let u = self.webuser, let p = self.webp else {
completionHandler(.cancelAuthenticationChallenge, nil)
return
}
let creds = URLCredential.init(user: u, password: p, persistence: .forSession)
completionHandler(.useCredential, creds)
}
}
我一直在尝试设置一个 web view wrapper 应用程序来加载网站的内容(仍待启动)。目前,该网站处于开发模式,该网站的唯一端点受 http 身份验证保护。
我一直在看这个解决方案:
但是,我不想每次都发出 POST 请求,但我宁愿对网站进行一次身份验证并保持连接。
我正在寻找一个干净稳定的解决方案,一个可以让我能够控制边缘情况的解决方案,例如提供的错误凭据。
我不习惯使用 NSURLConnection,因为该解决方案在 iOS9 中已被弃用。我需要一个 NSURLSession 的解决方案。
如果我在上述链接的解决方案中遗漏了某些内容,请告诉我。我相信也有人遇到过这个问题。此外,该网站具有 SSL 保护。
亲切的问候
您不需要使用 POST 或连接或 session。您应该只创建一个可变 URL 请求并设置一个身份验证 header。然后要求网页视图加载请求。
Auth header 来自维基百科的详细信息:
- 用户名和密码由一个冒号组合而成。
- 生成的字符串使用 Base64 的 RFC2045-MIME 变体编码,但不限于 76 char/line。
- 然后将授权方法和 space 即 "Basic " 放在编码字符串之前。
例如,如果用户代理使用 Aladdin 作为用户名,使用 OpenSesame 作为密码,则该字段构成如下:
Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l
我不完全确定这是否能以最佳方式满足您的需求,但如果您可以使用 WKWebView
,也许您可以简单地依赖身份验证质询委托方法?也请参阅我的回答 here,相关代码片段为:
func webView(webView: WKWebView, didReceiveAuthenticationChallenge
challenge: NSURLAuthenticationChallenge,
completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
let creds = NSURLCredential(user:"username", password:"password", persistence: NSURLCredentialPersistence.ForSession)
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, creds)
}
我自己还没有尝试过,但文档说凭据应该用于 session,因此链接产生的其他请求应该有效。即使没有,也只会导致再次调用该方法,您可以再次提供凭据。
这只是个小问题,您必须从警报等中获取名称和密码(您也可以更优雅地存储凭据,以便后续调用委托方法更优雅)。
您还写道您正在使用 SSL,所以我认为您熟悉 App Transport Security 标志(因为问题标题中只有 "HTTP" 而不是 "HTTPS",您可能希望它顺利运行,否则请参阅我链接的问题)。
好的,这是 Swift 3 代码。
extension MyController: WKNavigationDelegate {
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
guard let u = self.webuser, let p = self.webp else {
completionHandler(.cancelAuthenticationChallenge, nil)
return
}
let creds = URLCredential.init(user: u, password: p, persistence: .forSession)
completionHandler(.useCredential, creds)
}
}