14

I have implemented an OAuth2 client, in which the first step is to send a user to the relevant 3rd party (facebook for this example), I set them a state cookie, and when they return from facebook I validate that state cookie.

In Chrome, everything is great. When I send the user to the redirect URL, I can see (using inspect element) that they have the state cookie I set. However, when I try on (desktop) safari on latest MacOS, I don't see that cookie.

I set the cookie in the response for my redirect request:

res.cookie('state', state.toString(), {
  maxAge: 3600000,
  secure: true,
  httpOnly: true,
});
res.redirect(someRedirectUri);

How can I get those cookies to be saved on Safari as well? Am I just setting the cookies wrong?

Amit
  • 5,924
  • 7
  • 46
  • 94

3 Answers3

13

I think you've found known WebKit issue.

So safari is ignoring the Set-Cookie header when encountering the 302 HTTP status

Yevhen Laichenkov
  • 7,746
  • 2
  • 27
  • 33
2

Late response but I hope this helps anyone else coming across this issue.

I ran into this issue earlier today. It was happening on iOS Safari and Chrome (Chrome on iOS uses WebKit). The workaround I implemented was changing the initial response to a 200 and return a web page which would do a JavaScript redirect in a few seconds.

Here's the HTML I used:

<html lang="en">
<head>
    <title>Redirecting...</title>
</head>
<body>
    <h1>Redirecting...</h1>
    <div>You will be redirected in a moment. If you are not redirected, click the following link: <a id="link" href="https://example.com">Go Now</a></div>
    <script type="text/javascript">
        var host = "https://"+window.location.host;
        document.getElementById("link").setAttribute("href", host);
        setTimeout(function(){
            window.location.href = host;
        }, 3000);
    </script>
</body>
</html>

This way the Cookies will be set with the response, and the redirect will happen a moment later.

In my case, I was completing an OAuth workflow. You should be able to customize/render the page in a number of ways to meet other requirements.

Padge
  • 81
  • 6
0

I came across this question and the answers when investigating a problem I have with cookies and an OAuth2 client (actually oidc). My problem turned out to be different, so it is not a good answer to the original question, but hopefully it will prevent others reading this from going on a wild goose chase.

I have a backend that sets a session cookie (__ac_session) with information that is used during the authentication with the oidc server. Problems:

  1. At first it looked like this cookie was not saved in the browser, because it was sent in a redirect response. I tried doing the redirect in javascript, from the answer by Padge, but that did not help. Problem was that the cookie was only set on a path (/acl_users/oidc) and both Safari and Chrome did not show this cookie when looking at the homepage. Firefox does show it, but I had unrelated problems with that browser.

  2. So the browser did get the cookie and sent it along with further requests on that path. But the cookie never reached the backend. The problem here was that I had the Varnish caching server in front of the backend, and this removed most cookies, including this one, to improve anonymous caching.

I don't know if you get this with standard Varnish, but with my configuration I did. Relevant part of the final varnish.vcl after I fixed it:

/* cookies for pass */
set req.http.UrlNoQs = regsub(req.url, "\?.*$", "");
if (req.http.Cookie && req.http.Cookie ~ "auth_token|__ac(|_(name|password|persistent|session))=") {
    if (req.http.UrlNoQs ~ "\.(js|css|kss)$") {
        unset req.http.cookie;
        return(pipe);
    }
    return(pass);
}

My backend is Plone with an oidc plugin. Here is a link to my full issue report, created when I did not yet know the cause.

maurits
  • 2,355
  • 13
  • 16