[Fixed]-Django no csrftoken in cookie

23👍

I think you should provide the code how you get the csrf token in your HTML/JS code and settings for your middlewares.

First of all you should check that django.middleware.csrf.CsrfViewMiddleware is turned on.

I had a similar issue, when in python code I used request.META.get('CSRF_COOKIE') to get the token.

When you use this token in template – {% csrf_token %} Django notes that the token was rendered and sets the Cookie in CsrfViewMiddleware.process_response. If you get the token value in other way Django will miss this flag. So it will generate you a token but will not set the corresponding cookie.

I have 2 workarounds in code. You should add it to your views that are used to generate templates with JS code.

1. You can force Django to set the CSRF Cookie:

# Force updating CSRF cookie
request.META["CSRF_COOKIE_USED"] = True

2. Django sets the CSRF_COOKIE_USED automatically if you call get_token

from django.middleware.csrf import get_token
# don't use direct access to request.META.get('CSRF_COOKIE')
# in this case django will NOT send a CSRF cookie. Use get_token function
csrf_token = get_token(request)

Each one of this solutions should work separately. I advice to use get_token

👤Igor

16👍

You probably want to use the ensure_csrf_cookie view decorator (available since Django 1.4). This will set the csrftoken cookie even if you don’t use the {{ csrf_token }} template tag.

6👍

I had the same problem ($.cookie(‘csrftoken’) returned ‘undefined’).

The problem was in my Django configuration, I commented the following line and it works:

#CSRF_COOKIE_HTTPONLY = True  # Prevent client-side JavaScript access to the CSRF cookie
👤o_c

3👍

First of all, if you are designing the application, it is always better to use csrf Token in a header or in POST request rather than in a cookie, because:

  • All forms must have the value added to its HTML dynamically. Any AJAX
    POSTs must also include the value.
  • The cookie will be submitted for every request (i.e. all GETs for
    images, CSS, JS, etc, that are not involved in the CSRF process)
    increasing request size.

If you want to force usage of cookies in django, you could always:

request.META["CSRF_COOKIE_USED"] = True

in your project if you are not using {% csrf_token %} anywhere. According to [documentation][1], you are not required to do anything else, but write a simple javascript code. Actually it’s not true. You have to put "request.META['CSRF_COOKIE_USED'] = True" line in every view (or write appropriate decorator).

2👍

Expanding on o_c’s answer: by commenting the CSRF_COOKIE_HTTPONLY line, csrf_token value is no longer ‘undefined’ (in Firefox firebug) and is shown as the ‘real’ value, e.g. ‘qGuPe2Q7… etc.’.

Ajax request is no longer rejected with 403 Forbidden error and is correctly executed (provided that csrf_token is set in the AJAX header).

        $.ajaxSetup({
            beforeSend: function(xhr, settings) {
                 if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                 xhr.setRequestHeader("X-CSRFToken", csrftoken);
                }
             }
        });

Leave a comment