9

在正常情况下,django 会通过 cookie 发送 csrf 令牌,稍后 ajax post 方法可以使用该令牌。但是,当我在浏览器(Chrome 或 Firefox)中清除 cookie 时,csrf 令牌不再发送到浏览器,会话 ID 仍在发送但没有 csrf 令牌。有谁知道出了什么问题?

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

4

4 回答 4

5

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

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

两种解决方案:

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

有关详细信息,您可以参考django doc

于 2015-11-19T02:25:39.517 回答
4

查看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

检查哪个适用于您。

于 2012-07-17T06:23:00.277 回答
1

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

于 2019-12-26T06:33:52.500 回答
0

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

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

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

另请参阅相关主题:在没有表单元素的 Django 中使用 ajax 请求

于 2013-04-25T02:13:21.423 回答