Safari API calls not sending sessionid cookie withCredentials: true


#1

Hello,

I’ve been struggling for some time with this and I’m wondering if anyone here can help.

I have an app that is accessing an external API. Upon login, the server is sending a session id that I’m using to authenticate all subsequent data calls. Chrome and Android are working fine. Safari and iOS are not.

The login code in my service is straightforward:

  public login(credentials): Observable<Object> {
    let httpParams = this.httpParams;
    for (let key in credentials){ httpParams = httpParams.set(key, credentials[key])};
    return this.httpClient.post(this.url + this.loginEndpoint, httpParams, { withCredentials: true });
}

and when it’s called:

this.authServiceProvider.login({username: this.username, password: this.password}).subscribe(data => {
    <display logged in page>
});

But as I make another call to the dataProvider, Safari is instantiating a new session on the server, ie. not sending the session id cookie from the previous request.

CORS is working. Here are the headers my server is sending, including the cookie.

access-control-allow-credentials: true
access-control-allow-headers: origin, x-requested-with, content-type
access-control-allow-origin: http://localhost:8100
content-encoding: gzip
content-length: 95
content-type: text/javascript
date: Wed, 21 Mar 2018 15:55:50 GMT
server: Apache-Coyote/1.1
set-cookie: JSESSIONID=BE1997D948436D29A90DA24DC518E29F; Path=/api/; HttpOnly
status: 200
vary: Origin,Accept-Encoding

and here are the headers that Chrome is sending on the following request:

:authority: api.com
:method: POST
:path: /api/login.jsp
:scheme: https
accept: application/json, text/plain, */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
content-length: 283
content-type: application/x-www-form-urlencoded;charset=UTF-8
cookie: JSESSIONID=BE1997D948436D29A90DA24DC518E29F; _ga=GA1.2.744976386.1521627198; _gid=GA1.2.533597894.1521627198
origin: http://localhost:8100
referer: http://localhost:8100/?ionicplatform=android&http://localhost:8100/ionic-lab
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36

and here are the headers that Safari is sending for the second request:

Referer: http://localhost:8100/?ionicplatform=android&http://localhost:8100/ionic-lab
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Origin: http://localhost:8100
Host: api.com
Accept: application/json, text/plain, */*
Connection: keep-alive
Accept-Language: en-us
Accept-Encoding: br, gzip, deflate
Content-Length: 283
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0.2 Safari/604.4.7

If I go into Safari’s preferences and uncheck Security > Website tracking > Prevent cross-site tracking, everything works as expected. Safari sends the cookie.

Referer: http://localhost:8100/?ionicplatform=android&http://localhost:8100/ionic-lab
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Origin: http://localhost:8100
Host: api.com
Accept: application/json, text/plain, */*
Connection: keep-alive
Accept-Language: en-us
Accept-Encoding: br, gzip, deflate
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0.2 Safari/604.4.7
Cookie: JSESSIONID=32D79DD5171A6B82783252CE22E55083
Content-Length: 283

But obviously this is not a solution for users of the iOS app.

Anyone have any experience with this? I’ve found a lot of people with similar issues over the years but most of the solutions haven’t worked for me :frowning_face:

Any help is most appreciated! And let me know if you need any more information.


#2

One (not very nice) option would be to use the native http instead of the Angular one and handle cookies manually :confused:


#3

Thanks for the reply! I’m hoping I don’t have to do that. I will try to persuade the owners of the API with which I am working to implement a token-based authentication scheme rather than a cookie based one.


#4

That would indeed be a much better option. Cookies and Safari are really hard to get right…


#5

Did you ever figure out the root cause of this? I’m seeing the exact same thing and can’t figure it out. I’m considering the same workaround of using local storage / Authorization header instead of cookies, though this isn’t as secure.


#6

@chromacoma @dmittendorf did you find a viable solution?

I’m facing the same issue…

Related: https://stackoverflow.com/questions/47309048/enable-cross-site-tracking-in-wkwebview?rq=1