简体   繁体   English

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

[英]django CSRF token cookie not set for some users

I have been getting sporadic CSRF errors in an app that is mostly working ok. 在大多数正常运行的应用程序中,我一直遇到零星的CSRF错误。 I do everything as I'm supposed to do: I use {% csrf_token %} in my template for normal forms and in my ajax POSTs I set the X-CSRFToken header: 我应该做的所有事情:我在模板中使用{% csrf_token %}以获取普通表单,并在我的ajax POST中设置X-CSRFToken标头:

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

I'm even forcing the cookie to be set in all views by writing a custom Middleware that calls get_token 我什至通过编写调用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

Everything works OK in my localhost and in production for most users. 在我的本地主机和大多数用户的生产环境中,一切正常。 But for some users I get 403 CSRF validation error. 但是对于某些用户,我会收到403 CSRF验证错误。

I added a lot of debug info. 我添加了很多调试信息。 Turns out that even if CsrfViewMiddleware is setting the csrftoken is setting the cookie in the response, in the actual browser the cookie is not set ( $.cookie('csrftoken') is null ). 事实证明,即使CsrfViewMiddleware设置了csrftoken也在响应中设置cookie,在实际的浏览器中也没有设置cookie( $.cookie('csrftoken')null )。 So when the ajax call is made, there is no cookie present in the request. 因此,在进行ajax调用时,请求中没有cookie。

So, I guess this pretty much means that some users' browsers are blocking this cookie? 因此,我想这几乎意味着某些用户的浏览器正在阻止此Cookie? Anyone else had this experience? 其他人有这种经历吗?

Most browsers have an option to "block all cookies". 大多数浏览器都有“阻止所有cookie”选项。 You may want to detect that in javascript and give your users a warning that some functional cookies are required for the site to work correctly. 您可能想在javascript中检测到该错误,并向您的用户发出警告,要求某些功能性cookie才能使网站正常工作。 There's another SO question that shows how to do that. 还有另一个SO问题显示了如何执行此操作。

Alternatively, grab the token from a hidden input field ( {% csrf_token %} will add that field in your template). 或者,从隐藏的输入字段中获取令牌( {% csrf_token %}将在您的模板中添加该字段)。 That should always work. 那应该一直有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM