【发布时间】:2014-02-25 09:16:44
【问题描述】:
几天前,我重置了本地烧瓶环境,但在删除之前没有通过pip freeze 捕获依赖项。因此我不得不重新安装整个堆栈的最新版本。
现在出乎意料的是,我不再能够使用表单进行验证。 Flask 声称 CSRF 会丢失。
def register():
form = RegisterForm()
if form.validate_on_submit():
...
return make_response("register.html", form=form, error=form.errors)
第一次发送Get 时,我按预期检索了一个空的form.errors。
现在我填写表格并提交,form.errors 显示:{'csrf_token': [u'CSRF token missing']}
这太奇怪了。我想知道 Flask-WTF 是不是变了,我用错了。
我可以清楚地看到form.CSRF_token 存在,为什么它声称它丢失了?
CSRFTokenField: <input id="csrf_token" name="csrf_token" type="hidden" value="1391278044.35##3f90ec8062a9e91707e70c2edb919f7e8236ddb5">
我从未接触过工作模板,但我还是把它贴在这里:
{% from "_formhelpers.html" import render_field %}
{% extends "base.html" %}
{% block body %}
<div class="center simpleform">
<h2>Register</h2>
{% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %}
<form class="form-signin" action="{{ url_for('register') }}" method=post>
{{form.hidden_tag()}}
<dl>
{{ render_field(form.name) }}
{{ render_field(form.email) }}
{{ render_field(form.password) }}
{{ render_field(form.confirm) }}
<dd><input type=submit value=Register class='btn btn-primary'>
</dl>
</form>
</div>
{% endblock %}
这是一个新错误吗?
更新:
我已重新安装所有内容,但问题仍然存在。
正如 Martijn 建议的那样,我正在flask_wtf 中调试以下方法:
def validate_csrf_token(self, field):
if not self.csrf_enabled:
return True
if hasattr(request, 'csrf_valid') and request.csrf_valid:
# this is validated by CsrfProtect
return True
if not validate_csrf(field.data, self.SECRET_KEY, self.TIME_LIMIT):
raise ValidationError(field.gettext('CSRF token missing'))
最后一个条件是引发验证错误。
field.data = "1391296243.8##1b02e325eb0cd0c15436d0384f981f06c06147ec"
self.SECRET_KEY = None (? Is this the problem)
self.TIME_LIMIT = 3600
你是对的,HMAC 比较失败了……这两个值每次都不同。
return hmac_compare == hmac_csrf
我在我的配置中定义了 SECRET_KEY 和 CSRF_SESSION_KEY。
【问题讨论】:
-
您接受 cookie 吗? CSRF 架构要求
csrf_token值在会话中存在且有效;它是一个随机值,用于对令牌进行签名,并在发布时用于使用表单验证 CSRF 令牌(连同服务器端密钥)。 -
是的,Firefox 和 Chrome 都不会阻止 cookie。我不明白。
-
所以,为了验证,您确实看到了一个名为
session的 cookie 集(前提是您没有将SESSION_COOKIE_NAME设置为其他值)? -
是的。在调试监视列表下的 Eclipse 中,当我输入
session时,我得到这个:LocalProxy: <SecureCookieSession {'csrf_token': '2182effc89ce180a53622272d88d4466679920cd'}> -
我遇到这个问题很久了,意识到这是我的
SESSION_COOKIE_SECURE = True应用程序设置。希望这对其他人有帮助。
标签: python forms flask flask-wtforms