未为某些用户设置 django CSRF 令牌 cookie

django CSRF token cookie not set for some users

我在一个大部分工作正常的应用程序中遇到了零星的 CSRF 错误。我按照我应该做的做所有事情:我在我的模板中使用 {% csrf_token %} 作为普通表单,在我的 ajax POST 中我设置 X-CSRFToken header:

$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
    },
});

我什至通过编写调用 get_token

的自定义中间件强制在所有视图中设置 cookie
def CSRFForceCookieMiddleware(get_response):
    def middleware(request):
        response = get_response(request)
        get_token(request) # Force to set cookie in all responses
        return response
    return middleware

在我的本地主机和大多数用户的生产环境中一切正常。但是对于某些用户,我收到 403 CSRF 验证错误。

我添加了很多调试信息。事实证明,即使 CsrfViewMiddleware 正在设置 csrftoken 正在响应中设置 cookie,但在实际浏览器中未设置 cookie($.cookie('csrftoken')null)。因此,当进行 ajax 调用时,请求中不存在 cookie。

那么,我想这很可能意味着某些用户的浏览器正在阻止此 cookie?其他人有过这种经历吗?

大多数浏览器都有 "block all cookies" 的选项。您可能希望在 javascript 中检测到这一点,并警告您的用户网站需要一些功能性 cookie 才能正常工作。还有另一个 SO question 展示了如何做到这一点。

或者,从隐藏的输入字段中获取令牌({% csrf_token %} 会将该字段添加到您的模板中)。这应该总是有效的。