【问题标题】:Flask-WTF SelectField with CSRF protection enabled启用 CSRF 保护的 Flask-WTF SelectField
【发布时间】:2013-05-24 17:23:21
【问题描述】:

我在提交包含动态填充的 SelectField 的表单时遇到问题。由于某种原因,当 Flask 尝试验证 CSRF 令牌时,当 SelectField 在表单中时它总是失败。当我从表单中删除 SelectField 时,它会成功验证 CSRF 令牌。

有人遇到过这种行为吗?

编辑

表格:

class AddToReportForm(Form):
    selectReportField = SelectField(u'Reports',choices=[('test1','test')])

    def __init__(self, *args, **kwargs):
        """
        Initiates a new user form object
        :param args: Python default
        :param kwargs: Python default
        """
        Form.__init__(self, *args, **kwargs)




    def validate(self,id_list):
        rv = Form.validate(self)

        if not rv:
            print False
            #Check for the CSRF Token, if it's not there abort.
            return False

        print True
        return True

神社2:

<form  method=post name="test">
{{ form.hidden_tag()}}




    {{ form.selectReportField }}
    <a href="#" onclick="$(this).closest('form').submit()" class="button save">Add to report</a>

</form>

渲染:

form = AddToReportForm()
return render_template('random',title='add reports',form=form

【问题讨论】:

  • 你能贴一些代码吗?
  • 是的,我会做一个概念:)
  • 更新了一些代码
  • 你确定是 CSRF 失败而不是其他原因吗? SelectField.choices 看起来有点可疑,不应该是 (value, label) 元组的列表,而不仅仅是字符串吗?
  • 是的更新了,在我的代码中它确实是一个元组。

标签: python flask csrf


【解决方案1】:

你在哪里设置 SECRET_KEY?它必须在 Form 类中可用:

class AddToReportForm(Form):
    selectReportField = SelectField(u'Reports',choices=[('test1','test')])
    SECRET_KEY = "myverylongsecretkey"

    def __init__(self, *args, **kwargs):
        """
        Initiates a new user form object
        :param args: Python default
        :param kwargs: Python default
        """
        Form.__init__(self, *args, **kwargs)
    def validate(self,id_list):
        rv = Form.validate(self)

        if not rv:
            print False
            #Check for the CSRF Token, if it's not there abort.
            return False
        return True

或在应用程序引导程序中:

app = Flask(__name__)
app.secret_key = 'myverylongsecretkey'

或在构造函数中:

form = AddToReportForm(secret_key='myverylongsecretkey')
return render_template('random',title='add reports',form=form)

【讨论】:

  • 密钥在应用程序的配置文件中设置,它适用于所有表单,除了我使用 SelectField 的表单。
  • 不完全确定,因为我对 Flask 生态系统还不是很熟悉,但总的来说,将密钥直接放入源代码被认为是一种不好的做法。
【解决方案2】:

我仍然看不到 SelectField 和 CSRF 之间的任何联系。 validate 方法有点可疑,额外的参数会触发以下测试用例,但就目前而言,这似乎工作得很好:

from flask import Flask, render_template_string
from flaskext.wtf import Form, SelectField

app = Flask(__name__)
app.debug = True
app.secret_key = 's3cr3t'


class AddToReportForm(Form):
    selectReportField = SelectField(u'Reports', choices=[('test1', 'test')])


@app.route('/test', methods=['GET', 'POST'])
def test():
    form = AddToReportForm()
    if form.validate_on_submit():
        print 'OK'
    return render_template_string('''\
<form method=post name="test">
{{ form.hidden_tag()}}
{{ form.selectReportField }}
<input type="submit">
</form>
''', form=form)


app.run(host='0.0.0.0')

【讨论】:

  • 问题最终是数据库中 id 的类型转换,而这应该是为 SelectField 强制转换的。
【解决方案3】:

推荐使用:

app.secret_key = 'key here' # key user defined

【讨论】:

    猜你喜欢
    • 2014-02-25
    • 2017-08-17
    • 2015-11-27
    • 2012-12-20
    • 2013-06-16
    • 1970-01-01
    • 2017-01-08
    • 2018-03-11
    • 1970-01-01
    相关资源
    最近更新 更多