Setcookie() Does Not Set Cookie in Google Chrome

Why Chrome can’t set cookie

If you want to do some background reading then I suggest you look for guides to CORS (cross-origin resource sharing) and, specifically, how to set cookies when using CORS.

Using your original code you'll need to change it to set withCredentials to true:

let response = await axios({
method: 'post',
url: 'http://127.0.0.1:3000/api/login', // my Node server on 3000 port
data: {
email : login,
password: password,
},
withCredentials: true
})

Behind the scenes this will set the withCredentials flag on XMLHttpRequest:

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials

You'll then get CORS errors in your console. If you work your way through those errors you should be able to get it working. These errors will include...

Firstly, the server will need to return the header Access-Control-Allow-Credentials: true. This also applies to the preflight OPTIONS request.

Secondly, you're currently using Access-Control-Allow-Origin: * but that isn't allowed for requests using credentials. That'll need to be Access-Control-Allow-Origin: http://www.example.com. Likewise for the preflight.

At that point the cookie should be set in most browsers (more on browser quirks later).

To get the cookies added to subsequent requests you'll also need to set withCredentials: true on those requests. The other header changes outlined above also need to be applied. The cookies will not be included on the preflight request, just the main request.

Seeing the cookies in the browser's developer tools is not completely straightforward. Generally the tools only show cookies set for the same origin as the current page, which doesn't include the cookies set via CORS requests. To see those cookies you'll need to open another browser tab and set the URL to something that starts with the same origin as the CORS request. Be careful though, you need to pick a URL that won't set the cookies itself, otherwise that doesn't really prove anything.

Another way to check what cookies are set is to send another request (with withCredentials) and see what cookies get sent.

Then we have the browser-specific issues...

In Safari it is really difficult to get cookies to set over CORS. If Safari is a target browser for you then I suggest doing some further research into that.

Secondly, Chrome 80 is due to change the rules around CORS cookies significantly. See:

https://www.chromium.org/updates/same-site

You'll already see warnings about this in your console with older versions of Chrome. In short, CORS cookies will need to be served over https and set the directives Secure and SameSite=None.

Update:

Since writing this answer I have created an FAQ for common CORS problems. The section explaining the use of cookies can be found at https://cors-errors.info/faq#cdc8.

Set-Cookie is not working in Chrome and Dolphin - with two websites

A cookie ... was set without the `SameSite` attribute.

Starting July 14 (2020), you should set these 1,2 and upgrade to Django 3.1 3,4 (released Aug 4):

SESSION_COOKIE_SECURE = True
SESSION_COOKIE_SAMESITE = 'None'

Explanation

Before Django 3.1, the samesite attribute is not set if the setting is the None singleton:

if samesite:
if samesite.lower() not in ('lax', 'strict'):
raise ValueError('samesite must be "lax" or "strict".')
self.cookies[key]['samesite'] = samesite

As of Django 3.1, the samesite attribute is set for the 'None' string; still not for None/False:

if samesite:
if samesite.lower() not in ('lax', 'none', 'strict'):
raise ValueError('samesite must be "lax", "none", or "strict".')
self.cookies[key]['samesite'] = samesite

References

  1. Cookies default to SameSite=Lax - Chrome Platform Status
  2. Reject insecure SameSite=None cookies - Chrome Platform Status
  3. Settings | Django documentation | Django #std:setting-SESSION_COOKIE_SAMESITE
  4. Allowed setting SameSite cookies flags to 'None' · Pull Request #11894 · django/django

setcookie() do not set value in chrome

If your using CakePHP why not do it their way?

public $components = array('Cookie');

$cookieTime = '8 weeks'; //The amount of time you want the cookie to last

if ( !empty($voice_choice) )
this->Cookie->write('voice_choice', $voice_choice, true, $cookieTime);

Also for debugging cookies a nice trick in Chrome is:

Inspect Element -> Resources Tab -> Cookies -> yoursite (local.yoursite.com) to see if the cookie is being written.

Can't set cookie in Chrome Dev tools on localhost

Turned out I have to set an expiration date for MyCookie (all this in DevTools). However, this is confusing because:

  1. I'm pretty much sure it worked without an expiation date before.
  2. i18next cookie has no expiration date and sits there just fine.


Related Topics



Leave a reply



Submit