Losing cookies in WKWebView
Asked Answered
P

3

10

When I create new request for WKWebView with authentication cookie and send the request, WKWebView correctly loads protected web page:

let req = NSMutableURLRequest(URL: NSURL(string: urlPath)!)
let headers = NSHTTPCookie.requestHeaderFieldsWithCookies([myAuthCookie]);
req.allHTTPHeaderFields = headers;
webView.loadRequest(req)

The problem is, that when user clicks on a any link in the web page, with new request WKWebView loses authentication cookie and is redirected to logon page. Cookie domain and path are filled and correct.

I am aware of the missing functionality of WKWebView mentioned here.

Thanks in advance for any idea.

Portion answered 20/11, 2014 at 15:19 Comment(2)
I've been struggling with this very issue for days now. It seems baffling that cookie storage/usage would be so broken in WKWebView. Looking forward to hearing any solutions to this.Verbalize
Possible duplicate of Can I set the cookies to be used by a WKWebView?Inflate
C
8

The best thing to do is to store your cookie into the

[NSHTTPCookieStorage sharedHTTPCookieStorage]

Then each time you want to load the request, call this function instead:

- (void)loadRequest:(NSURLRequest *)request {
        if (request.URL) {
            NSDictionary *cookies = [NSHTTPCookie requestHeaderFieldsWithCookies:[[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:request.URL]];
            if ([cookies objectForKey:@"Cookie"]) {
                NSMutableURLRequest *mutableRequest = request.mutableCopy;
                [mutableRequest addValue:cookies[@"Cookie"] forHTTPHeaderField:@"Cookie"];
                request = mutableRequest;
            }
        }

        [_wkWebView loadRequest:request];
}

It extract the right cookies from shared cookies and includes it into your request

Cutcheon answered 9/12, 2015 at 13:46 Comment(5)
WKWebViews's loadRequest returns WKNavigation* instead of void: [developer.apple.com/reference/webkit/wkwebview/…Berga
You commented: "Then each time you want to load the request, call this function instead: - (**void**)loadRequest:(NSURLRequest \*)request ". WKWebView's loadRequest returns **WKNavigation* ** instead of ** void ** . What you wrote works perfectly with UIWebViews, but the opening question mentioned WKWebViews.Berga
Well it works actually (I use it in a wrapper for UIWebview/WkWebview ). It loads the request but we just don't use the resultCutcheon
I need help here @TheWindwakerKerril
? I don't see your issue hereCutcheon
H
2

I suppose when you set it in the request you are sending the cookie to the server but NOT setting it in the WKWebview. The cookies are usually set by the server in the "Set-Cookie" header and then it should be persisted. So if if you don't have an issue with cookie passing all the way to the server and back you can do a trick:

  1. send the cookie in the first request
  2. make the server send it back in the "Set-Cookie" header
  3. every subsequent request should have the cookie

I haven't tried the approach yet but will be very surprised if it doesn't work.

The alternative as mentioned by Sebastien could be do inject it via javascript. Be mindful though that you cannot set "HTTP-Only" flag this way and the cookie will be available by all the scripts running (https://www.owasp.org/index.php/HttpOnly).

I'm still trying to find a natural way to set the cookie but I don't think it exists.

Hope it helps.

Hoffman answered 2/3, 2015 at 21:46 Comment(3)
Hi alex, do you know if anything has changed here? Are cookies handled any better in WKWebView?Hydrolyte
Hi JLaw, have a look here developer.apple.com/library/prerelease/ios/releasenotes/General/… I think they have provided the good way to handle cookies in iOS9 though I haven't tried it myselfHoffman
This is great, just what I needed for my Node.js custom server. Can't believe I didn't think of it. I was modeling the cookie uptake process in reverse. Of course the server needs to send Set-Cookie to make WKWebView to integrate it back into its internal (opaque!?! Argh) cookie store. When WKWebView includes it in a loadRequest, it's an arbitrary sent header. The web server by default sees no need to echo back 'Set Cookie' -- it rightly assumes the browser already has it.Barytone
H
0

You can inject some javascript into the we view to load the cookies so that requests initiated by the web view will also have your cookies. See the answer to this question for more details:

https://mcmap.net/q/142952/-can-i-set-the-cookies-to-be-used-by-a-wkwebview

Hellbox answered 25/2, 2015 at 12:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.