我有一个本地运行在127.0.0.1:8000上的Django应用。当我通过浏览器上的127.0.0.1:8000访问它时,一切都很好。但是,当我通过localhost:8000访问它时,发生CSRF错误:我认为这是由于AJAX POST请求未正确发送csrftoken
cookie。
在同一HTML页面上,我有两个操作提交POST请求:
一个带有html form
且使用Django模板标签{% csrf_token %}
的HTML插件(效果很好)
另一种使用Fetch API(AJAX)向Django应用程序中的视图提交POST请求,该视图发送回JSON(请注意,我我未使用django-rest-framework ),而这一方法不起作用。
获取请求如下所示:
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(...)
但是,当我发出该请求时,我的视图返回了一个Forbidden (CSRF cookie not set.)
错误。如果我添加一个@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
据我了解,Django的CSRF保护针对CSRF_COOKIE
的{{1}}检查HTTP_X_CSRFTOKEN
或HTTP_COOKIE
。如您所见,csrftoken
中没有csrftoken
(尽管在我的JS中,我可以做HTTP_COOKIE
,但它可以工作!)。我认为这是导致CSRF错误的原因。
是否知道如何在我的请求的getCookie('csrftoken')
中包含csrftoken
?
编辑:这不是this question的重复项,如您所见,我已经在请求中添加了HTTP_COOKIE
,所以凭据确实被传递了。