我知道这是一个常见的问题,但是在考虑了每个网络解决方案后,我仍然得到了#CSR; CSRF令牌丢失或不正确。"错误。
ajax调用正确使用了django在常见的csrf解决方案上创建的cookie crsf令牌:
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", window.csrftoken);
}
}
这是POST标题:
Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7,es;q=0.6
Connection:keep-alive
Content-Length:31
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Cookie:csrftoken=PV730Sh7PhMM4WKlnSmzMv726Y5wspf4LKHz8XR9TfHVeY167a8aAzbU8Oci6VMf
Host:127.0.0.1:8000
Origin:http://localhost:3000
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
X-CSRFToken:uD3NP6tHllrSSnx4qi23EVgIZy0dkVE5qhZCYN5A9ZETI8SITPb0NGtamIezFTPv
在DJANGO,我正在使用中间件:
'django.middleware.csrf.CsrfViewMiddleware',
Django View doens没有@csrf选项,因为它是一个验证POST。
从标题中可以看出,我的Ajax Call从另一个"端口"开始。 (反应申请)。对于开发,我已在Chrome中禁用了跨源检查以确保我的呼叫正常进行。
这是一段Django视图:
def login(request, *args, **kwargs):
username = request.POST['username']
password = request.POST['password']
c = {}
try:
user = authenticate(request,username=username, password=password)
if user is not None:
return JsonResponse(user.id, safe=False, status=200)
我担心标题。正如您所看到的,X-CSRFToken
(由第一次使用选项@ensure_csrf_cookie
进行GET调用后由Django创建)与Cookie:csrftoken=
不同,我不知道它在哪里得到
我尝试通过在发送ajax配置之前添加一行来覆盖它,如下所示:
xhr.setRequestHeader(" Cookie:csrftoken",csrftoken);
但有了这个(我不知道为什么)请求没有开始。
我没有其他想法。
感谢您的帮助!
答案 0 :(得分:0)
不要从Cookie中发送此信息,请使用params数据发送此信息。因为我通常通过JQuery AJAX发送。不要通过标题发送。
var formdata = {
"csrfmiddlewaretoken":$("input[name='csrfmiddlewaretoken']").val()
}
你也可以试试很多答案。 "CSRF token missing or incorrect" while post parameter via AJAX in Django
答案 1 :(得分:0)
有一个简单易用的解决方案:
使用JavaScriptCookie,你可以得到它:
var csrftoken = Cookies.get('csrftoken');
var data = new FormData();
data.append('someOtherData', someOtherData);
data.append('csrftoken', csrftoken);
$.ajax({
type: "POST",
url: "someUrl",
data: data,
});
您应该使用FormData
,因为它让您感觉很简单。
如果您不想使用第三方,请查看此documentation。这也是提到的第三方,也是没有它的方式。