0

I have the following situation.

Part I:

  • localhost:3000 is frontend (React)
  • localhost:8000 is backend (Django)
  • I make a successful cross-domain GET (I'm using django-cors-headers package)

Part of the response headers:

Set-Cookie: csrftoken=token; expires=Fri, 16-Feb-2018 10:56:00 GMT; Max-Age=31449600; Path=/
  • the cookie csrftoken is not being set in the browser (if I'm right, it's due to the browser ignoring cookies from a different domain), although I have it set to allow third-party cookies and site data (in Chrome's settings)
  • POST fails due to csrf cookie not being set

Part II:

  • I set the cookie manually
  • everything works perfect

This is my ajax request:

jQuery.ajaxSetup({
  beforeSend: function(xhr, settings) {
    xhr.setRequestHeader("X-CSRFToken", csrftoken);
  }
});

jQuery.ajax({
  url: url,
  type: 'POST',
  data: {attr: value, csrfmiddlewaretoken: csrftoken},
  crossDomain: true,
  xhrFields: {
    withCredentials: true
  }
})

Is there any way to read the cookie after the initial GET and set it in the browser?

sideshowbarker
  • 62,215
  • 21
  • 143
  • 153
dnmh
  • 1,745
  • 1
  • 25
  • 43

2 Answers2

2

I had a similar issue recently using django and angular 2, I had a problem with the configuration of django-cors-headers.

What is your django-cors-headers? You can not set allow all and allow credentials at the same time.

This is not allowed:

CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True

Use instead:

CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
    'localhost:3000',
    '127.0.0.1:3000'
)

Set-Cookie response header not working using Angular 2 + django-rest-framework

Community
  • 1
  • 1
F. Caron
  • 576
  • 5
  • 17
  • I have CORS_ALLOW_CREDENTIALS = True and CORS_ORIGIN_WHITELIST = ('localhost:3000', '127.0.0.1:3000') but it's not helping. – dnmh Feb 18 '17 at 00:03
  • 1
    Ah, I got it... I didn't have this in my ajax call: xhrFields: { withCredentials: true } – dnmh Feb 18 '17 at 00:30
0

If you are able to see the cookie in the Response Headers but not see them in the storage of the browser, the Issue might be related to the Samesite settings on the cookie. By default, django sets cookies with Samesite=Lax, which prevents cross-orign access of cookies.

on the cookie settings you can do this:

response.set_cookie('csrf_token', token, max_age=31449600, samesite=None, secure=False)

Please note that setting a cookie with samesite=None is dangerous and it should be set with secure=True, to ensure that cookies are only accessed on secure connections. But in this case, where you are on localhost, you can just set it up like that and make sure to change it for the production environment.

The MDN Documentation on SameSite cookies gives more details on SameSite cookies.

In your settings.py file, you should also allow cross-origin requests by setting these:

CORS_ALLOW_CREDENTIALS = True
CORS_ALLWED_ORIGINS = [
    'http://localhost:8000',
    'http://localhost:3000'
]

You should also ensure that you set withCredentials: true in your request. Refer to this post on how to set it.

I-Richy
  • 11
  • 2