【问题标题】:WKWebview injecting cookie header cause redirect loopWKWebview注入cookie标头导致重定向循环
【发布时间】:2016-10-21 13:19:19
【问题描述】:

我正在尝试将我单独获取的会话 cookie 注入到 WKWebview 请求中,结果证明这很痛苦......

我设法使用this solution 注入会话cookie,如下:

// Acquiring the cookies
let cookies = HTTPCookie.cookies(withResponseHeaderFields: headers, for: s.request!.url!)

//Appending all the cookies into one raw string.
var cookiesRawString = ""
for c in cookies {
   cookiesRawString += "\(c.name)=\(c.value); "
}

var req: URLRequest = try! URLRequest(url: URL, method: method)

// Then the injection itself
request.setValue(cookiesRawString, forHTTPHeaderField: "Cookie")

webView.load(req)

让我用伪代码快速解释一下服务器逻辑:

  1. 服务器收到对端点 /endpoint1 的调用,并附加了初始会话 cookie
  2. 然后继续将客户端重定向到 /endpoint2,并在 url 中附加用户生成的令牌。
  3. 请求附加令牌的第二个端点会导致最终重定向到 /endpoint3,其中 Set-Cookie 标头包含一次会话 cookie
  4. /endpoint3 附加一次性会话 cookie 会导致 200 响应,并且用户被识别。

问题是,由于某种原因,当我使用上述方法将 cookie 附加到初始请求时,会导致重定向循环,而在 Android 平台上它可以完美运行(我在那里使用了类似的注入方法)。

我看到它们之间的唯一区别是 android 应用程序仅在初始请求时注入 cookie,并且所有后续重定向调用都没有这些会话 cookie。 虽然 ios 在所有重定向调用中重复初始会话 cookie(甚至忽略服务器 set-cookie 标头并附加初始会话 cookie..)。

我做错了吗?如何让 wkwebview 仅在初始请求时使用注入的 cookie?

编辑1:也尝试回退到UIWebview,但它产生相同的结果,似乎将cookie作为标头注入并不好,但我尝试使用HTTPCookieStorage,但它不会保存cookie

// the count is 7
var cookiesCount = HTTPCookieStorage.shared.cookies(for: s.request!.url!)?.count

let cookies = HTTPCookie.cookies(withResponseHeaderFields: headers, for: s.request!.url!)

for c in cookies {
   HTTPCookieStorage.shared.setCookie(c)
}

// Count is still 7!            
cookiesCount = HTTPCookieStorage.shared.cookies(for: s.request!.url!)?.count

编辑 2: 好吧,我发现 UIWebview 正在使用 cookie 存储的全局实例,与 alamofire 相同(我用它来获取会话 cookie),因此无需手动添加 cookie,站点识别用户。

但我仍然更喜欢使用 WKWebview,因为 UIWebview 内存泄漏会飞速发展(在几个网页导航后超过 100 mb!)。

有没有办法在 WKWebview 中使用全局 cookie jar(被 alamofire 使用)??

【问题讨论】:

    标签: ios swift redirect cookies wkwebview


    【解决方案1】:

    我认为这可能无关紧要,但我遇到了类似的问题。

    原因是修改后的 cookie 弄乱了我使用 NSURL.sharedSession 的所有后续请求。事实证明,使用 WKWebView 设置的 cookie 正在清除 NSURLSession.sharedSession 中的标头。我认为 cookie 存储在多个会话之间共享。所以,我最终使用了 EphemeralSession,而不是 sharedSession。

    【讨论】:

      【解决方案2】:

      我设法让它在 WKWebview 上运行,使用了一个 hackish 解决方案:

      func webView(_ webView: WKWebView, decidePolicyFor navigationAction:
                     WKNavigationAction, decisionHandler: 
                     @escaping (WKNavigationActionPolicy) -> Void) {
      
          let url = navigationAction.request.url!.absoluteString
      
          if UserAppendix.isLogin && url != previousNavigateUrl {
              previousNavigateUrl = url
              if url.contains("/endpoint1") {
                  let headerFields = navigationAction.request.allHTTPHeaderFields
                  let headerIsPresent = headerFields!.keys.contains("Cookie")
      
                  if headerIsPresent {
                      decisionHandler(WKNavigationActionPolicy.allow)
                  } else {
      
                      var req = URLRequest(url: navigationAction.request.url!)
                      let cookies = NetworkAppendix.httpSessionCookies
                      let values = HTTPCookie.requestHeaderFields(with: cookies)
                      req.allHTTPHeaderFields = values
                      webView.load(req)
      
                      decisionHandler(WKNavigationActionPolicy.cancel)
                  }
              }
              else if firstTime {
                  firstTime = false
      
                  let req = URLRequest(url: navigationAction.request.url!)
                  webView.load(req)
      
                  decisionHandler(WKNavigationActionPolicy.cancel)
      
      
              }
              else {
                  decisionHandler(.allow)
              }
          }
          else {
              decisionHandler(.allow)
          }
      }
      

      我在第一个请求中设置了 cookie,在第二个请求中中断流程并创建一个新请求(使用重定向 url),为了避免我在第一个请求中设置的会话 cookie,所有后续请求都被处理一样。

      我知道它并不完美,但它可以完成工作。

      【讨论】:

      • 感谢您提供此解决方法,但是,我体验过以后使用webview.goBack() 会在页面之间不断循环,可能是每次您加载新的 UrlRequest 时。你有同样的经历吗?
      猜你喜欢
      • 2010-10-19
      • 2014-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多