来自AJAX的CRSF对Django不正确

时间:2018-01-31 10:45:55

标签: ajax django cookies

我知道这是一个常见的问题,但是在考虑了每个网络解决方案后,我仍然得到了#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);

但有了这个(我不知道为什么)请求没有开始。

我没有其他想法。

感谢您的帮助!

2 个答案:

答案 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。这也是提到的第三方,也是没有它的方式。