WKWebview注入cookie头导致重定向循环



我正试图将我单独获得的会话cookie注入到WKWebview请求中,这证明是相当痛苦的…

我设法使用这种解决方案注入会话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(甚至忽略server 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后几个网页导航!)。

是否有一种方法来使用全局cookie罐(alamofire使用)在WKWebview??

我认为这可能是无关的,但我有一个类似的问题。

原因是修改的cookie弄乱了我使用NSURL.sharedSession的所有后续请求。事实证明,使用WKWebView的cookie集正在从nsursession . sharedsession中清除header。我认为cookie存储是跨多个会话共享的。因此,我最终使用了EphemeralSession,而不是sharedSession。

我设法让它在WKWebview上工作,使用一个hack的解决方案:

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,所有后续请求都被相同对待。

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

相关内容

  • 没有找到相关文章