WKWebview注入cookie标头导致重定向循环 [英] WKWebview injecting cookie header cause redirect loop

查看:259
本文介绍了WKWebview注入cookie标头导致重定向循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将我已经单独获取的会话cookie注入到WKWebview请求中,这真是很痛苦...

I'm trying to inject session cookies I've acquired separately into a WKWebview request, which turns out to be quite a pain...

我设法使用注入会话Cookie解决方案,如下所示:

I managed to inject the session cookies using this solution, as follows:

// 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)

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

Let me quickly explain the server logic with pseudo code:


  1. 服务器接收到附加了初始会话cookie的端点 / endpoint1 的呼叫

  2. 然后继续进行操作将客户端重定向到 / endpoint2 ,并在URL中添加用户生成的令牌。

  3. 请求第二个端点并添加令牌,最终重定向到 /带有Set-Cookie标头的Endpoint3 标头包含一个时间会话Cookie

  4. / endpoint3 ,其中附加了一个时间会话Cookie,结果为200,用户

  1. Server receive call to endpoint /endpoint1 with initial session cookies appended
  2. It then proceed to redirect the client to /endpoint2 with user generated token appended in the url.
  3. requesting the second endpoint with token appended results in the final redirect to /endpoint3 with Set-Cookie header containing one time session cookies
  4. /endpoint3 with the one time session cookies appended results in 200 response, and the user is recognized.

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

The problem is that for some reason the when I append the cookies to the initial request using the method above, it results with a redirect loop, while on the Android platform it works flawless (I used there a similar injection method).

我唯一看到的区别是android应用仅在初始请求上注入了cookie,随后所有的重定向调用都没有这些会话cookie。
,而ios 在所有重定向调用上都重复了初始会话Cookie (甚至忽略了服务器set-cookie头并附加了初始会话Cookie。)。

The only difference that I saw between them was that the android app injected the cookies only on the initial request, and all the subsequent redirect calls were without those session cookies. While the ios repeated the initial session cookies on all the redirect calls (even ignoring the server set-cookie header and appending the initial session cookies..).

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

Am I doing something wrong? How can I make the wkwebview use the injected cookies only on the initial request?

编辑1:也尝试过使用UIWebview,但是它产生的结果相同,看来将该cookie作为标题注入是不好的,但是我尝试使用HTTPCookieStorage,但它不会保存cookie

Edit 1: Also tried falling back to UIWebview, but it produces the same results, it seems that injecting the cookies as a header is not good, but I tried using HTTPCookieStorage, but it won't save the cookies!

// 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),因此不需要

Edit 2: Well I found out the UIWebview is using a global instance of the cookie storage, the same as alamofire (which I've used to fetch the session cookies), so there was no need to add the cookies manually, the site recognized the user.

但是我仍然更喜欢使用WKWebview,因为UIWebview内存泄漏迅速增加(几个网页后超过100 mb)导航!)。

But I still prefer to use WKWebview, as the UIWebview memory leak sky rockets (over 100 mb after couple of web pages navigation!).

是否可以在WKWebview中使用全局cookie jar(由alamofire使用)?

Is there a way to use the global cookie jar (used by alamofire) in WKWebview??

推荐答案

我设法通过一个拙劣的解决方案在WKWebview上工作:

I managed to get it working on WKWebview, using a hackish solution:

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,在第二个请求上中断了流程并创建了一个新请求(带有重定向网址),以避免我在

I set the cookies on the first request, and on the second request break the flow and create a new request (with the redirect url), to avoid the session cookies I set on the first request, all subsequent requests are treated the same.

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

I know it's not perfect, but it gets the job done.

这篇关于WKWebview注入cookie标头导致重定向循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆