Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Losing cookies in WKWebView

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.

like image 874
jiri.huml Avatar asked Nov 20 '14 15:11

jiri.huml


People also ask

Does WKWebView store cookies?

The code above has no effect with the new web view since each WKWebView instance has its own cookie storage represented by WKHTTPCookieStore class.

Is WKWebView deprecated?

Since then, we've recommended that you adopt WKWebView instead of UIWebView and WebView — both of which were formally deprecated. New apps containing these frameworks are no longer accepted by the App Store.

Does WKWebView share cookies with Safari?

WKWebView is an in-app browser that displays web content. It doesn't share cookies or web site data with other WKWebView instances, or with the Safari browser.

Is WKWebView secure?

The WKWebView is a modern API applying all the modern web security mechanisms, it's still maintained by Apple and gets updates. The good thing about WKWebView is that it does out-of-process rendering, so if the attackers find a memory corruption vulnerability in it, your application's process is still isolated.


2 Answers

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

like image 124
The Windwaker Avatar answered Oct 20 '22 18:10

The Windwaker


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.

like image 45
Alex Avatar answered Oct 20 '22 18:10

Alex