简体   繁体   English

localhost:8000 上的 Django “禁止(未设置 CSRF cookie。)”

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

I have a Django app running locally on 127.0.0.1:8000.我有一个 Django 应用程序在 127.0.0.1:8000 上本地运行。 When I access it via 127.0.0.1:8000 on my browser, everything is fine.当我在浏览器上通过 127.0.0.1:8000 访问它时,一切都很好。 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.但是,当我通过 localhost:8000 访问它时,会发生 CSRF 错误:我认为这是由于 AJAX POST 请求未正确发送csrftoken cookie。

On the same HTML page, I have two actions that submit POST requests:在同一个 HTML 页面上,我有两个提交 POST 请求的操作:

  • one with an html form using the Django template tag {% csrf_token %} (that one works perfectly well)一个带有 html form ,使用 Django 模板标签{% csrf_token %} (那个效果很好)

  • 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. 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.但是当我提出请求时,我的视图返回一个Forbidden (CSRF cookie not set.)错误。 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_exempt装饰器(它消除了错误,但我不想永久停用 CSRF)并打印request.META.get("CSRF_COOKIE")request.META.get("HTTP_X_CSRFTOKEN")request.META.get("HTTP_COOKIE") ,这是我得到的:

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 .据我了解,Django 的 CSRF 保护检查CSRF_COOKIEHTTP_X_CSRFTOKENHTTP_COOKIEcsrftoken As you can see, there is no csrftoken in my HTTP_COOKIE (altough in my JS I can do getCookie('csrftoken') and it works.).如您所见,我的HTTP_COOKIE中没有csrftoken (尽管在我的 JS 中我可以执行getCookie('csrftoken')并且它有效。)。 I think this is what is causing the CSRF error.我认为这就是导致 CSRF 错误的原因。

Any idea how to include the csrftoken in my request's HTTP_COOKIE ?知道如何在我的请求的HTTP_COOKIE中包含csrftoken吗?

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.编辑:这不是这个问题的重复,如您所见,我已经在我的请求中添加了credentials: 'include' ,因此凭据确实会被传递。

Try doing:尝试做:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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