Django 1.9 AJAX form CSRF token 403 error - "CSRF cookie not set"

I have seen a lot about this on SO, but nothing can fix my problem.

Problem:

With CSRF middleware enabled, Django responds to an AJAX 403 form request, indicating:

"CSRF cookie not set."

After the documentation , JS functionality was implemented, which sets the user header "X-CSRFToken .

It works as expected, receives a "csrftoken" cookie from the browser and sends it along with the AJAX request:

x-csrftoken: 1a0u7GCQG0wepZHQNThIXeYpMy2lZOf2 

But the answer is still 403.

Tried solutions:

I tried everything I could find on SO or the Internet, in particular:

  • Checking for middleware:

     MIDDLEWARE_CLASSES = [ ... 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', ... ] 
  • Various browsers with cookies enabled;

  • The @ensure_csrf_cookie my presentation @ensure_csrf_cookie ;

  • Setting {% csrf_token %} in my template;

  • Using the render shortcut, which accepts the request request context;

  • Custom CSRF_COOKIE_NAME and CSRF_HEADER_NAME settings.py in my settings.py ;

  • Explicitly set CSRF_COOKIE_SECURE = False and CSRF_COOKIE_HTTPONLY = False ;

  • Explicit setting CSRF_TRUSTED_ORIGINS ;

  • Testing on the development and production server;

  • Even request.META["CSRF_COOKIE_USED"] = True , in my opinion, as someone suggested.

And nothing worked out.

Headers:

If I use @csrf_exempt and print(request.META) , in my opinion, it is clear that the user header "X-CSRFToken" is present in the request and formatted according to the Django documentation with the "HTTP_" prefix, hyphens are replaced with underscores, all uppercase letters: "HTTP_X_CSRFTOKEN" .

Moreover, this value matches the cookie set by Django.

Cookies

It is strange if I try to print(request.COOKIES) in my view, on the page and form loading I see the file "csrftoken" , but the dictionary is empty at the request of AJAX . Could this be a problem?

I am desperately trying to find what is actually wrong. Thanks for reading this.

+6
ajax django cookies csrf fetch-api
source share
1 answer

Ok, the problem is pretty simple:

The Fetch API does not send credentials by default. According to MDN :

The read-only credential property of the request interface indicates whether the user agent should send cookies from another domain in the case of cross-origin requests. This is similar to XHR withCredentials, but with three values ​​available.

omit used by default and it never sends cookies. You just need to add the same-origin to the arguments to the fetch() function:

 fetch(formUrl, { ... credentials: 'same-origin', ... }) 

And you will be fine :)

+6
source share

All Articles