在正常情况下,django将通过cookie发送csrf令牌,以后可以使用ajax post方法。但是,当我在浏览器(Chrome或Firefox)中清除cookie时,csrf令牌不再发送到浏览器,会话ID仍在发送但没有csrf令牌。有谁知道出了什么问题?
我通过将{%csrf_token%}添加到我的模板来解决了这个问题,并且SET-COOKIE标题与该页面请求一起出现。事实证明,您必须将{%csrf-token%}放入模板中,以使服务器通过SET-COOKIE标头发送令牌
答案 0 :(得分:4)
我遇到了同样的问题。针对django源调试后,原因是:
如果您的视图未呈现包含csrf_token的模板 模板标签,Django可能不会设置CSRF令牌cookie。
两种解决方案:
{% csrf_token %}
@ensure_csrf_cookie
装饰器进行观看有关详细信息,请参阅django doc。
答案 1 :(得分:3)
查看声明了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 :(得分:1)
就我而言,问题是VSCode调试器。 我通过VSCode调试模式打开服务器,然后打开新的隐身窗口(显然没有cookie),django停止设置缺少的cookie。 当我正常启动服务器时,问题就消失了。
答案 3 :(得分:0)
在大多数情况下,由前一个答案中提到的第二次检查引起的问题
if not request.META.get("CSRF_COOKIE_USED", False):
return response
这可以通过使用@ensure_csrf_cookie装饰器来解决。如果使用 - 每次呈现视图时都会传递检查并设置/更新cookie。