【问题标题】:django does not send csrf token again after browser cookies has been cleared清除浏览器 cookie 后,django 不再发送 csrf 令牌
【发布时间】:2012-07-16 00:40:46
【问题描述】:

在正常情况下,django 会通过 cookie 发送 csrf 令牌,供 ajax post 方法使用。但是,当我在浏览器(Chrome 或 Firefox)中清除 cookie 时,csrf 令牌不再发送到浏览器,会话 id 仍在发送但没有 csrf 令牌。有谁知道怎么回事?

我通过将 {% csrf_token %} 添加到我的模板中解决了这个问题,并且 SET-COOKIE 标头与该页面请求一起出现。事实证明,您必须将 {%csrf-token%} 放入模板中才能使服务器通过 SET-COOKIE 标头发送令牌

【问题讨论】:

    标签: django cookies


    【解决方案1】:

    查看django/middleware/csrf.py,其中声明了CsrfViewMiddleware 类。正如您在def process_response(self, request, response) 中看到的,有三种情况会阻止 cookie 设置:

    def process_response(self, request, response):
        if getattr(response, 'csrf_processing_done', False):
            return response
    
        # If CSRF_COOKIE is unset, then CsrfViewMiddleware.process_view was
        # never called, probaby because a request middleware returned a response
        # (for example, contrib.auth redirecting to a login page).
        if request.META.get("CSRF_COOKIE") is None:
            return response
    
        if not request.META.get("CSRF_COOKIE_USED", False):
            return response
    
        # Set the CSRF cookie even if it's already set, so we renew
        # the expiry timer.
        response.set_cookie(settings.CSRF_COOKIE_NAME,
                            request.META["CSRF_COOKIE"],
                            max_age = 60 * 60 * 24 * 7 * 52,
                            domain=settings.CSRF_COOKIE_DOMAIN,
                            path=settings.CSRF_COOKIE_PATH,
                            secure=settings.CSRF_COOKIE_SECURE
                            )
        # Content varies with the CSRF cookie, so set the Vary header.
        patch_vary_headers(response, ('Cookie',))
        response.csrf_processing_done = True
        return response
    

    检查哪个适用于您。

    【讨论】:

      【解决方案2】:

      在大多数情况下,问题是由上一个答案中提到的第二次检查引起的

      if not request.META.get("CSRF_COOKIE_USED", False):
              return response
      

      这可以通过对视图使用@ensure_csrf_cookie 装饰器来解决。如果使用 - 检查通过并在每次呈现视图时设置/更新 cookie。

      另见相关主题:Using ajax request in Django without form element

      【讨论】:

        【解决方案3】:

        我遇到了同样的问题。针对django源码调试后,原因是:

        如果您的视图未呈现包含 csrf_token 的模板 模板标签,Django 可能不会设置 CSRF 令牌 cookie。

        两种解决方案:

        • 在您的模板中添加{% csrf_token %}
        • 为您的视图使用 @ensure_csrf_cookie 装饰器

        详情可以参考django doc

        【讨论】:

        • 几乎让我头晕目眩,试图弄清楚为什么会出现“CSRF 令牌丢失或不正确”。首次成功登录后。 @ensure_csrf_cookie 解决了,谢谢!
        【解决方案4】:

        就我而言,问题在于 VSCode 调试器。 我通过 VSCode 调试模式打开服务器,然后打开新的隐身窗口(显然没有 cookie),django 停止设置丢失的 cookie。 当我正常启动服务器时,问题就消失了。

        【讨论】:

        • 欢迎来到 SO!你的答案在今天很有用,但在 7 年前就没有用了……
        猜你喜欢
        • 1970-01-01
        • 2021-10-27
        • 2016-06-02
        • 2016-07-16
        • 2017-06-06
        • 1970-01-01
        • 2019-12-03
        • 2021-08-02
        • 2019-01-07
        相关资源
        最近更新 更多