WKWebView does not process "Set-Cookie" header correctly
Asked Answered
M

0

8

I use WKWebView in my project to implement web-based authorisation UI. I use [NSHTTPCookieStorage sharedHTTPCookieStorage] to keep user session cookies of whole app and keep user authenticated in case of WKWebView redirects to our Backend pages.

The problem is that it looks like WKWebView ignores "Set-Cookie" header for other domains in this case. For example:

Initial request to setup authentication process:

GET /api2/providers/misfit/start/ HTTP/1.1
Host: api.welltory.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate
Connection: keep-alive
Proxy-Connection: keep-alive
Cookie: csrftoken=haF3PX9l6VB9DrTJTNEQvsjsAiMZTYNC;sessionid=txo4fhez18vl6mvjuwlelph1uyn1pkau
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/601.6.17 (KHTML, like Gecko) Version/9.1.1 Safari/601.6.17
X-CSRFToken: haF3PX9l6VB9DrTJTNEQvsjsAiMZTYNC
Referer: https://api.welltory.com/api2/api/version/
Accept-Language: ru

The result of this request is redirect to target service login page, where we have request listed below:

GET /auth/dialog/authorize?scope=public+birthday+email+tracking+session+sleeps&state=NdhVfDpcCTfjCkuEbgnoj0E4s8pnw6wv&client_id=ZkwJzk9QvaEkzL4M&response_type=code&redirect_uri=https%3A%2F%2Fapi.welltory.com%2Fapi2%2Fproviders%2Fmisfit%2Ffinish%2F%3Fredirect_state%3DNdhVfDpcCTfjCkuEbgnoj0E4s8pnw6wv HTTP/1.1
Host: api.misfitwearables.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
X-CSRFToken: haF3PX9l6VB9DrTJTNEQvsjsAiMZTYNC
Connection: keep-alive
Proxy-Connection: keep-alive
Cookie: csrftoken=haF3PX9l6VB9DrTJTNEQvsjsAiMZTYNC;sessionid=txo4fhez18vl6mvjuwlelph1uyn1pkau
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/601.6.17 (KHTML, like Gecko) Version/9.1.1 Safari/601.6.17
Accept-Language: ru
Referer: https://api.welltory.com/api2/api/version/
Accept-Encoding: gzip, deflate

HTTP/1.1 302 Moved Temporarily
Content-Type: text/html; charset=UTF-8
Date: Tue, 19 Jul 2016 11:15:01 GMT
Location: /auth/login
Set-Cookie: connect.sid=s%3AROcF81HPxNkajBr1z3s4MI8e.5nm4JigW3g6FnemCzM2SMYXF%2Bed0xxvcAjIwhwTe4ro; Path=/; HttpOnly
Vary: Accept
X-Powered-By: Express
Content-Length: 78
Connection: keep-alive

<p>Moved Temporarily. Redirecting to <a href="/auth/login">/auth/login</a></p>

Here we see Set-Cookie header. And I expect to see this cookie in next redirected request made by api.misfitwearables.com itself. But what I see here is next:

GET /auth/login HTTP/1.1
Host: api.misfitwearables.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: keep-alive
Proxy-Connection: keep-alive
Cookie: csrftoken=haF3PX9l6VB9DrTJTNEQvsjsAiMZTYNC;sessionid=txo4fhez18vl6mvjuwlelph1uyn1pkau
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/601.6.17 (KHTML, like Gecko) Version/9.1.1 Safari/601.6.17
Accept-Language: ru
Referer: https://api.welltory.com/api2/api/version/
Accept-Encoding: gzip, deflate

I've passed the same test with standalone Safari and all behaviour was as I expected.

I don't understand what are able to influence WKWebView this way. I'll appreciate any suggestions of the way I could investigate this strange behaviour.

UPD: Interesting thing that I noticed is if first request contains Cookie header then Set-Cookie from all subsequent responses does not work. Looks like a bug and I have no idea how to fix it.

UPD2: As I noticed by looking at other requests, Set-Cookie worked correctly. But it seems that HTTP client think a 3xx redirects sequence as a single request, each of which might bring the same HTTP headers as first one, without paying attention to domains of final destination URL.

So if first request has "X-CSRFToken: haF3PX9l6VB9DrTJTNEQvsjsAiMZTYNC" header, second and third ones have it either. The same logic applied to Cookie.

And since most of headers have really good reasons to become replicated from request to request during redirect sequence execution, Cookie header is not so obvious. I didn't find any direct rules about this behaviour.

BTW, in my case while first redirect is made by backend developed in my team, I asked server developer to avoid using redirects from our server this way and provide me with direct url of target server to start authorisation process.

Merchantable answered 19/7, 2016 at 11:52 Comment(5)
Met almost same problem. Do you have a workaround?Coordinate
I am facing exactly the same problem with WKWebview.. Have any workaround?Grime
Sorry, but I didn't find a good solution for this on my side. Finally we've decided to avoid such redirects on our server.Merchantable
Seems like using the old UIWebView is the smart thing to do for login/authentication.Nugatory
I would recommend trying SFViewController instead if it is acceptable by your App design. I don't know if it has the same problem. But what important is an access to shared Safari context with all sessions, saved passwords etc. It is very useful in case of using external auth providers with a web interface. Actually, it's significant enough to force a designer take it into account from the very beginning.Merchantable

© 2022 - 2024 — McMap. All rights reserved.