即使包含csrf令牌,Django CSRF验证也会失败 [英] Django CSRF verification failed even when csrf token is included
问题描述
我了解到,提交时表单中未包含csrf令牌时会发生此错误,但这次并非如此。
I understand that this error occurs when the csrf token isn't include in the form when submitting, but this is not the case this time.
我正在尝试登录到管理站点。管理员登录表单中包含csrf令牌,我可以看到该csrf令牌的值与csrf cookie的值匹配。另外,当我提交时,我可以看到相同的csrf令牌已发布到服务器。
I am trying to login to the admin site. The admin login form has csrf token included, and I can see the value of that csrf token matches the csrf cookie's value. Also, when I submit, I can see that the same csrf token is posted to the server.
但是,我仍然得到 CSRF验证失败
消息。我确定是否清除cookie会起作用,但是我不明白为什么会发生这种情况?
But still, I get the CSRF verification failed
message. I am sure if I clear the cookies it will work, but I don't understand why this happens?
关于会话引擎设置的注意事项:
One thing to note about my session engine setting:
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
我不知道此设置是否重要,但我应该指出。
I don't know if this setting matters, but I should point it out.
更新:好的,我打开了调试功能,这里有更多信息:
Update: Ok, I turned on debug and here are more info:
Reason given for failure:
CSRF cookie not set.
通常,当存在真正的跨站点请求伪造或Django的CSRF机制时,可能会发生这种情况未正确使用。对于POST表单,您需要确保:
In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:
您的浏览器正在接受cookie。
Your browser is accepting cookies.
我很确定我的浏览器接受cookie。因为我可以在浏览器中看到cookie值,所以也可以看到在http标头中设置了cookie:
I am pretty sure my browser accepts cookie. Because I can see the cookie value in my browser also I can see the cookie been set in the http header:
Set-Cookie:csrftoken=j2tSkjxUyeY90NZhUcMZ5GEdDKEa0wdW; expires=Fri, 12-May-2017 07:28:00 GMT; Max-Age=31449600; Path=/
view函数将请求传递给模板的render方法。
在模板中,每个POST表单中都有一个指向内部URL的{%csrf_token%}模板标签。
The view function passes a request to the template's render method. In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
由于我使用的是Django自己的管理页面,因此我确定每个以内部URL为目标的POST表单中都有一个{%csrf_token%}模板标记。
Since I am using Django's own admin pages, I am sure there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
另外,我可以看到post操作发生时,csrf值会传递:
Also, I can see when the post action happens, the csrf value is passed along:
csrfmiddlewaretoken=j2tSkjxUyeY90NZhUcMZ5GEdDKEa0wdW&username=cheng&password=&next=%2Fadmin%2F
出于明显的原因,我删除了密码字段的值。
I deleted the value for the password field for obvious reasons.
如果您未使用CsrfViewMiddleware,则必须在任何可使用此视图的视图上使用csrf_protect使用csrf_token模板标签,以及接受POST数据的模板标签。
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
嗯,我有我的settings.py文件中的CsrfViewMIddleWare
。另外,Django自己的管理站点知道如何处理csrf_token。
Well, I have the CsrfViewMIddleWare
in my settings.py file. Also, Django's own admin site knows how to handle csrf_token.
我以前见过此错误,因此我通过清除cookie来解决。但是对于不了解Cookie的普通用户来说,这可能是一个秀场停止者。我怀疑这与Cookie引擎设置有关。
I have seen this error before and I solved it by clearing cookies. But for regular users who don't know about cookies, this can be a show stopper. I suspect that it has something to do with the cookie-engine setting.
推荐答案
此问题可能是由于您的更改表单,即添加{%crsf_token%}并没有生效。刷新您的表单页,然后再次提供输入。可能效果很好。
This issue might be due to the fact that your changes to the form i.e adding the {% crsf_token %} didn't come to effect. Refresh your FORM PAGE, and then provide the inputs again. Might just work fine.
这篇关于即使包含csrf令牌,Django CSRF验证也会失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!