为啥我会收到“CSRF 令牌丢失或不正确”错误?

Posted

技术标签:

【中文标题】为啥我会收到“CSRF 令牌丢失或不正确”错误?【英文标题】:Why do I get a 'CSRF token missing or incorrect' error?为什么我会收到“CSRF 令牌丢失或不正确”错误? 【发布时间】:2017-09-01 12:31:25 【问题描述】:

我正在尝试从 Django 中的 View 函数返回一个值。该函数是从使用 Ajax 的 JavsScript 代码调用的,但我得到一个错误,上面写着“禁止(CSRF 令牌丢失或不正确)”。

javascript/Ajax

The Error message

html 代码如下所示:

    <div align="center" class="input-line">
     <form class="input-form" method="post">% csrf_token %
        <input type = "text" id = "ans" class = "form-control" name = "address" placeholder="Type postcode..."><br><br>
        <button id = "homeBtn" class="btn btn-primary">Find info</button><br><br>
     </form>
</div>

查看功能是:

    def result(request):
        if(request == 'POST'):
           param = request.form['my data']
           this = runAreaReview(param) #This returns a string
           return HttpResponse(this)

【问题讨论】:

我建议阅读Cross-Site Request Forgery,特别是防止它的“Cookie-to-Header Token”方法。 【参考方案1】:

对于任何遇到此线程的人,对于 Django 2.1,HEADER 键应该是 X-CSRFToken,链接在这里 https://docs.djangoproject.com/en/2.1/ref/csrf/

【讨论】:

【参考方案2】:

方法一

要使用 ajax 发出 post 请求,您需要设置一个名为 HTTP_X_CSRFTOKEN 的标头并将其值设置为以名称 csrftoken 存储在浏览器中的 cookie。 Reference。 所以在你的 ajax 调用中,你应该做这样的事情。

var csrftoken = Cookies.get('csrftoken');
 $.ajax(
     ...
     headers:"HTTP_X_CSRF_TOKEN":csrftoken
 );

还请注意,如果您正在使用带有 nginx 之类的反向代理服务器,请确保将此标头也转发给 django 应用程序。

方法2

您可以使用注释禁用此特定视图的 csrf 验证。 Reference

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def result(request):
    ...

方法3

出于安全原因,不推荐使用以下方法

如果您只是出于娱乐目的而非生产目的构建某些东西,您可以始终在设置中关闭 csrf 中间件以摆脱它。

【讨论】:

感谢您的建议。我使用了 csrf_exempt 并且它不再抛出该错误。但是现在它抛出一个错误,说 View 函数没有返回一个对象。它返回 None 而不是我已经在帖子本身中链接了我的视图函数,知道为什么会这样吗? 你应该检查request.method=="POST" 另外,我建议使用带有调试器的 IDE。它将帮助您查明问题,从而帮助您解决问题。 :)

以上是关于为啥我会收到“CSRF 令牌丢失或不正确”错误?的主要内容,如果未能解决你的问题,请参考以下文章

Unity Web Request + Django:CSRF 令牌丢失或不正确

Django 表单中的 CSRF 令牌丢失或不正确

禁止(CSRF 令牌丢失或不正确。)Django

Django:CSRF 令牌丢失或不正确。 / 避免 % csrf_token %

禁止(CSRF 令牌丢失或不正确)Django 错误

Django - CSRF 令牌丢失或不正确