Here is the workflow :
- I send an e-mail to a customer. This mail contains a link to my Angular application :
acme.com?token=abcd
- The user clicks on the link in the mail and is redirected to my application.
- A GET request is done. This response headers contains a
Set-Cookie XSRF:12345
- Then, after the GET response, a POST request is done, supposedly using the previous XSRF token.
Problem : on Safari/iPhone (and only on Safari/iPhone, it works on Safari/Mac), the cookie is not visible on JS side.
As a reminder, the XSRF cookie is intended to be read in JS and reinjected in the HTTP headers of subsequent POST/PUT/DELETE requests. As a result, the POST
request is sent without the XSRF header (but with the XSRF cookie) and ends with a 403 error. Everything works as if the cookie was HttpOnly
, but it's not !
Here is the full detail of the Set-cookie
:
Set-Cookie: XSRF=[...]; Expires=Thu, 23-Apr-2020 16:07:10 GMT; Path=/;SameSite=Strict;Secure
I suspected problems with the SameSite
policy because the user comes on the website after clicking on a link in an e-mail. So, I tried adding a rebound : after clicking, the user now lands on a acme.com/redirect.html?token=abcd
page that redirects to acme.com?token=abcd
(via window.location.href=...
)
As a matter of fact, it works... but I don't understand why. If it was a problem of SameSite
, why would the XSRF
cookie still be sent ? And, as it is not marked as HttpOnly
, why can't I read it on JS side ? Is there a way on Safari to investigate why the cookie is rejected ? Also, I found that some versions of Safari might have some bugs with cookie handling. Is there a way to deactivate SameSite policy on Safari/iPhone in order to understand if it comes from there ?