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 来自维基百科的详细信息:

  1. 用户名和密码由一个冒号组合而成。
  2. 生成的字符串使用 Base64 的 RFC2045-MIME 变体编码,但不限于 76 char/line。
  3. 然后将授权方法和 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)
    }
}