Django:在所有响应上强制 CSRF 令牌

Posted

技术标签:

【中文标题】Django:在所有响应上强制 CSRF 令牌【英文标题】:Django: Forcing CSRF token on all responses 【发布时间】:2015-11-20 18:53:24 【问题描述】:

我的网站有一个 AJAX POST 视图,可以从应用程序上的任何页面调用(事件跟踪)。此视图受 CSRF 保护。在某些情况下,CSRF cookie 没有设置,POST 调用失败。

我没有使用@ensure_csrf_cookie 手动装饰所有视图,我正在考虑编写我创建了一个中间件,强制 Django 在所有响应上设置 CSRF cookie。这种方法正确吗?它会造成我不知道的安全漏洞吗?

更新:这里是中间件代码:

from django.middleware.csrf import get_token

class ForceCsrfCookieMiddleware(object):
    def process_request(self, request):
        get_token(request)

【问题讨论】:

安全漏洞?我想不是。因为您只是在中间件中实现ensure_csrf_cookie 的功能。不过,请阅读该装饰器的源代码。 @Tzach 你如何在url.py 调用这个函数? 【参考方案1】:

不,只要您不将 csrf 令牌呈现在发布到外部站点的表单中,就没有问题(但无论如何,这将是一个问题,无论您在哪里实现它)。可以设置在一个中间件上,也可以设置在某些视图上,也可以设置在所有视图上,没关系。

CSRF 保护仅用于确保请求来自您的站点。无论您设置 cookie 的频率如何,如果请求包含正确的 CSRF 令牌,则意味着该请求确实来自您的站点,因为只有您的站点可以访问您的 cookie。 (当然,这仅在您没有将 CSRF 令牌泄露给第三方时才成立,例如通过将其发送到其他站点)

简而言之,这就是它的工作原理:

    服务器在响应中设置一个带有随机值的cookie 您的网站在发布数据时读取该值并将其发送到服务器 由于 cookie 只能从设置它们的同一域访问,因此其他站点无法读取该 cookie。因此,只要您收到具有正确 csrf 令牌的请求,就可以确保该请求来自您的站点。

关于 CSRF 的很好解释,请看这篇文章:http://www.gnucitizen.org/blog/csrf-demystified/

【讨论】:

以上是关于Django:在所有响应上强制 CSRF 令牌的主要内容,如果未能解决你的问题,请参考以下文章

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

Spring Security 在登录响应中使用新的会话令牌设置 CSRF

CSRF 令牌上的 Django 错误

我如何发送 CSRF 令牌

django csrf 令牌在每个请求上都必须是唯一的吗?

如何将 django csrf 令牌直接嵌入 HTML?