简体   繁体   中英

Django “Forbidden (CSRF cookie not set.)” on localhost:8000

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.

Try doing:

reqBody.append('csrfmiddlewaretoken', '{{ csrf_token }}')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM