I have a Django app running locally on 127.0.0.1:8000. When I access it via 127.0.0.1:8000 on my browser, everything is fine. However, when I access it via localhost:8000, CSRF errors occur : I think it is due to an AJAX POST request not properly sending the csrftoken
cookie.
On the same HTML page, I have two actions that submit POST requests :
one with an html
form
using the Django template tag{% csrf_token %}
(that one works perfectly well)another one that uses the Fetch API (AJAX) to submit a POST request to a view in my Django app that sends back a JSON (note that I am not using django-rest-framework), and this one doesn't work.
The fetch request looks like this :
const csrftoken = getCookie('csrftoken');
fetch(route, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken
},
credentials: 'include',
body: JSON.stringify(reqBody)
}).then(...)
But my view returns a Forbidden (CSRF cookie not set.)
error when I make that request. If I add a @csrf_exempt
decorator (which removes the error, but I don't want to deactivate CSRF permanently) to it and print request.META.get("CSRF_COOKIE")
, request.META.get("HTTP_X_CSRFTOKEN")
and request.META.get("HTTP_COOKIE")
, this is what I obtain :
CSRF_COOKIE: None
HTTP_X_CSRFTOKEN: cdd9hIG22C39heME5aUvBU8VfB9hpnnvf8TWLYMQBJsS8jqoPh0ErA7iq1fdHSt2
HTTP_COOKIE: isNotIncognito=true; _ga=GA1.1.1965841096.1569096679; ki_t=1569096680795%3B1569096680795%3B1569096748030%3B1%3B2; ki_r=; optimizelySegments=%7B%22172074712%22%3A%22false%22%2C%22172226670%22%3A%22none%22%2C%22172411375%22%3A%22ff%22%2C%22172441755%22%3A%22direct%22%7D; optimizelyBuckets=%7B%7D; optimizelyEndUserId=oeu1569096677162r0.6862028569293451; PGADMIN_KEY=f1f0faa8-c054-48c3-a42c-a98ba6e1a4d1; PGADMIN_LANGUAGE=en
From what I understand, Django's CSRF protection checks either CSRF_COOKIE
or HTTP_X_CSRFTOKEN
against HTTP_COOKIE
's csrftoken
. As you can see, there is no csrftoken
in my HTTP_COOKIE
(altough in my JS I can do getCookie('csrftoken')
and it works !). I think this is what is causing the CSRF error.
Any idea how to include the csrftoken
in my request's HTTP_COOKIE
?
EDIT : this is not a duplicate of this question, as you can see I have already added credentials: 'include'
to my request, so credentials do get passed on.