【问题标题】:CRSF incorrect to Django from AJAXCRSF 对来自 AJAX 的 Django 不正确
【发布时间】:2018-02-01 04:06:34
【问题描述】:

我知道这是一个常见问题,但在尝试了每个 Web 解决方案后,我仍然得到“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 没有任何 @csrf 选项,因为它是一个经过身份验证的 POST。

正如您从标题中看到的,我的 Ajax 调用从另一个“端口”(React 应用程序)开始。为了开发,我在 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(由 Django 在使用选项@ensure_csrf_cookie 进行第一次 GET 调用后创建)与 Cookie:csrftoken= 不同,我不知道它是从哪里获得的。

我尝试通过在发送 ajax 配置之前添加一行来覆盖它,如下所示:

xhr.setRequestHeader("Cookie:csrftoken", csrftoken);

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

我没有别的想法。

感谢您的帮助!

【问题讨论】:

    标签: ajax django cookies


    【解决方案1】:

    不要从 Cookie 发送这个,用 params 数据发送这个。例如,我通常通过 JQuery AJAX 发送。不要通过标头发送。

           var formdata = {
    "csrfmiddlewaretoken":$("input[name='csrfmiddlewaretoken']").val()
    }
    

    您也可以尝试许多答案。 "CSRF token missing or incorrect" while post parameter via AJAX in Django

    【讨论】:

      【解决方案2】:

      有一个简单的解决方案:

      使用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。这里也提到了第三方,也有没有它的方式。

      【讨论】:

      • 我尝试将令牌添加到 Ajax 调用数据作为您的代码,但它仍然无法正常工作。您链接的文档是我尝试过的第一件事,正如您在上面的代码中看到的那样。
      • 你是否包含了 JavaScriptCookie 库?
      猜你喜欢
      • 2016-01-21
      • 2019-06-08
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 2021-01-21
      • 2019-10-18
      • 2017-09-14
      相关资源
      最近更新 更多