【发布时间】:2016-09-09 02:43:59
【问题描述】:
我了解提交时表单中没有包含 csrf 令牌时会出现此错误,但这次不是这样。
我正在尝试登录管理站点。管理员登录表单包含 csrf 令牌,我可以看到该 csrf 令牌的值与 csrf cookie 的值匹配。另外,当我提交时,我可以看到相同的 csrf 令牌已发布到服务器。
但是,我仍然收到CSRF verification failed 消息。我确定如果我清除 cookie 它将起作用,但我不明白为什么会发生这种情况?
关于我的会话引擎设置需要注意的一点:
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
我不知道这个设置是否重要,但我应该指出。
更新:好的,我打开了调试,这里有更多信息:
Reason given for failure:
CSRF cookie not set.
一般来说,当有真正的跨站请求伪造时,或者没有正确使用 Django 的 CSRF 机制时,就会发生这种情况。对于 POST 表单,您需要确保:
您的浏览器正在接受 cookie。
我很确定我的浏览器接受 cookie。因为我可以在浏览器中看到 cookie 值,所以我也可以看到在 http 标头中设置了 cookie:
Set-Cookie:csrftoken=j2tSkjxUyeY90NZhUcMZ5GEdDKEa0wdW; expires=Fri, 12-May-2017 07:28:00 GMT; Max-Age=31449600; Path=/
视图函数将请求传递给模板的渲染方法。 在模板中,每个 POST 表单内都有一个 {% csrf_token %} 模板标签,以内部 URL 为目标。
由于我使用的是 Django 自己的管理页面,我确信there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
另外,我可以看到当 post 动作发生时,csrf 值被传递:
csrfmiddlewaretoken=j2tSkjxUyeY90NZhUcMZ5GEdDKEa0wdW&username=cheng&password=&next=%2Fadmin%2F
出于显而易见的原因,我删除了密码字段的值。
如果您不使用 CsrfViewMiddleware,那么您必须在任何使用 csrf_token 模板标签的视图以及接受 POST 数据的视图上使用 csrf_protect。
好吧,我的 settings.py 文件中有 CsrfViewMIddleWare。另外,Django 自己的管理站点知道如何处理 csrf_token。
我以前见过这个错误,我通过清除 cookie 解决了它。但是对于不了解 cookie 的普通用户来说,这可能是一个阻碍。我怀疑这与 cookie-engine 设置有关。
【问题讨论】:
-
或者,如果 cookie 验证设置正确,可能重复:Django CSRF failure after upgrade。我有类似的行为,并通过renaming the CSRF 和session cookie names 缓存现有的 CSRF cookie 来“修复”它。需要重命名会话 cookie 以强制用户登录以开始新会话。清除会话表是不够的。
标签: django