我重置了本地flask环境,但是没有通过捕获它的依赖项,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']}
form.errors
{'csrf_token': [u'CSRF token missing']}
真奇怪 我想知道Flask-WTF是否已更改,并且使用错误。
我可以清楚地看到form.CSRF_token存在,那么为什么声称它不存在呢?
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:
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。
在以下情况下,Flask-WTF CSRF基础结构将拒绝令牌:
令牌丢失。此处不是这种情况,你可以在表格中看到令牌。
它太旧了(默认到期时间设置为3600秒或一个小时)。TIME_LIMIT在表单上设置属性以覆盖此属性。这里可能不是这样。
TIME_LIMIT
如果'csrf_token'在当前会话中找不到密钥。你显然可以看到会话令牌,所以也可以看到。
'csrf_token'
如果HMAC签名不匹配;签名基于会话中在'csrf_token'密钥下设置的随机值,服务器端机密以及令牌中的到期时间戳记。
消除了前三种可能性后,你需要验证第四步失败的原因。你可以flask_wtf/csrf.py在validate_csrf()函数中的文件中调试验证。
flask_wtf/csrf.py
validate_csrf()
对于你的设置,你需要验证会话设置是否正确(尤其是如果你不使用默认会话配置),以及你使用的是正确的服务器端密码。表单本身可以SECRET_KEY设置属性,但在请求之间不稳定,或者应用程序WTF_CSRF_SECRET_KEY密钥已更改(后者默认为app.secret_keyvalue)。
SECRET_KEY
在0.9.0版中添加了CSRF支持,如果升级了,请查阅特定的CSRF保护文档。标准的Flask-WTF Form类包括 CSRF令牌作为隐藏字段,呈现隐藏字段足以包含它:
Form
{{ form.hidden_tag() }}