I'm testing to make a POST ajax request and I got a 403 because of no csrftoken. I followed the Document, however, it still doesn't work and I found that the cookie named csrftoken is empty, it means $.cookie("csrftoken")
return null.
Can someone tell me the reason and how to set csrftoken
into cookie?
If your view is not rendering a template containing the csrf_token template tag, Django might not set the CSRF token cookie. This is common in cases where forms are dynamically added to the page. To address this case, Django provides a view decorator which forces setting of the cookie: ensure_csrf_cookie() .
If you're using SessionAuthentication you'll need to include valid CSRF tokens for any POST , PUT , PATCH or DELETE operations. In order to make AJAX requests, you need to include CSRF token in the HTTP header, as described in the Django documentation.
CSRF tokens should not be transmitted using cookies. CSRF tokens in GET requests are potentially leaked at several locations, such as the browser history, log files, network appliances that log the first line of an HTTP request, and Referer headers if the protected site links to an external site.
The CSRF token is like an alphanumeric code or random secret value that's peculiar to that particular site. Hence, no other site has the same code. In Django, the token is set by CsrfViewMiddleware in the settings.py file. A hidden form field with a csrfmiddlewaretoken field is present in all outgoing requests.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With