1

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.

Ewaren
  • 1,343
  • 1
  • 10
  • 18
  • Possible duplicate of [Proper Django CSRF validation using fetch post request](https://stackoverflow.com/questions/43606056/proper-django-csrf-validation-using-fetch-post-request) – Kostas Charitidis Oct 23 '19 at 12:57
  • Try to assign directly to your header like this: `'X-CSRFToken':getCookie('csrftoken'),` I am thinking that maybe initializing as `constant` creates an issue – Kostas Charitidis Oct 23 '19 at 12:59

0 Answers0