WTForms FormField 导致 csrf_token 错误
WTForms FormField causing csrf_token errors
我有一个 Flask 项目,基本上有 2 个 Form Classes,它们在第三个 Form Class 中充当子表单。我将 2 个子表单与 FormField 字段一起使用。问题是当我提交表单时,两个子表单出现 csrf_token 错误。如果我在子表单中使用 csrf=false 属性 我不会得到这个,但这是否意味着我现在对 CSRF 攻击持开放态度?
class AddressForm(FlaskForm):
address = StringField(label='Address', validators=[DataRequired()])
address2 = StringField(label='Address 2', validators=[Optional()])
city = StringField(label='City', validators=[DataRequired()])
county = SelectField(label='County', validators=[DataRequired()], choices=[], coerce=int)
class Meta:
csrf = False
class NameForm(FlaskForm):
first_name = StringField(label='First Name', validators=[DataRequired(), Length(min=2)] )
last_name = StringField(label='Last Name', validators=[DataRequired(), Length(min=2)] )
class Meta:
csrf = False
class OrderForm(FlaskForm):
# Customer Details
customer_name = FormField(NameForm, separator='_')
customer_email = EmailField(label='Email', validators=[DataRequired(), Email()])
customer_mobile_phone = StringField(label='Mobile Phone Number', validators=[DataRequired()])
customer_alternative_phone = StringField(label='Alternative Phone Number', validators=[Optional()])
# Delivery Details
delivery_address = FormField(AddressForm, separator='_')
area = SelectField(label='Area', validators=[DataRequired()], coerce=int)
我已经在表格中包含了 {{ form.hidden_tag() }}
并且还配置了 SECRET_KEY。
您在表单标签中包含 {{ form.csrf_token }}
以使用 CSRF 保护。 Per the documentation,
When using a FlaskForm, render the form's CSRF field like normal.
<form method="post">
{{ form.csrf_token }}
</form>
If the template doesn't use a FlaskForm, render a hidden input with the token in the form.
<form method="post">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
</form>
您可能会发现参考有关基本使用说明的一般性 Flask-WTF documentation 很有帮助。
所以在大量搜索和观看视频后,我注意到在执行 FormFields 时,所有内容都指的是 Form 而不是 FlaskForm。看起来你在一个页面上只能有一个 FlaskForm……子表单必须是 Form class。我将我的子表单更改为从 Form 而不是 FlaskForm 继承并且它起作用了。 FlaskForm 继承自 Form,默认启用和配置 csrf。
- https://flask-wtf.readthedocs.io/en/stable/form.html
- https://flask-wtf.readthedocs.io/en/stable/api.html#flask_wtf.FlaskForm
- https://wtforms.readthedocs.io/en/2.3.x/forms/
class AddressForm(Form):
address = StringField(label='Address', validators=[DataRequired()])
address2 = StringField(label='Address 2', validators=[Optional()])
city = StringField(label='City', validators=[DataRequired()])
county = SelectField(label='County', validators=[DataRequired()], choices=[], coerce=int)
class NameForm(Form):
first_name = StringField(label='First Name', validators=[DataRequired(), Length(min=2)] )
last_name = StringField(label='Last Name', validators=[DataRequired(), Length(min=2)] )
我有一个 Flask 项目,基本上有 2 个 Form Classes,它们在第三个 Form Class 中充当子表单。我将 2 个子表单与 FormField 字段一起使用。问题是当我提交表单时,两个子表单出现 csrf_token 错误。如果我在子表单中使用 csrf=false 属性 我不会得到这个,但这是否意味着我现在对 CSRF 攻击持开放态度?
class AddressForm(FlaskForm):
address = StringField(label='Address', validators=[DataRequired()])
address2 = StringField(label='Address 2', validators=[Optional()])
city = StringField(label='City', validators=[DataRequired()])
county = SelectField(label='County', validators=[DataRequired()], choices=[], coerce=int)
class Meta:
csrf = False
class NameForm(FlaskForm):
first_name = StringField(label='First Name', validators=[DataRequired(), Length(min=2)] )
last_name = StringField(label='Last Name', validators=[DataRequired(), Length(min=2)] )
class Meta:
csrf = False
class OrderForm(FlaskForm):
# Customer Details
customer_name = FormField(NameForm, separator='_')
customer_email = EmailField(label='Email', validators=[DataRequired(), Email()])
customer_mobile_phone = StringField(label='Mobile Phone Number', validators=[DataRequired()])
customer_alternative_phone = StringField(label='Alternative Phone Number', validators=[Optional()])
# Delivery Details
delivery_address = FormField(AddressForm, separator='_')
area = SelectField(label='Area', validators=[DataRequired()], coerce=int)
我已经在表格中包含了 {{ form.hidden_tag() }}
并且还配置了 SECRET_KEY。
您在表单标签中包含 {{ form.csrf_token }}
以使用 CSRF 保护。 Per the documentation,
When using a FlaskForm, render the form's CSRF field like normal.
<form method="post"> {{ form.csrf_token }} </form>
If the template doesn't use a FlaskForm, render a hidden input with the token in the form.
<form method="post"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/> </form>
您可能会发现参考有关基本使用说明的一般性 Flask-WTF documentation 很有帮助。
所以在大量搜索和观看视频后,我注意到在执行 FormFields 时,所有内容都指的是 Form 而不是 FlaskForm。看起来你在一个页面上只能有一个 FlaskForm……子表单必须是 Form class。我将我的子表单更改为从 Form 而不是 FlaskForm 继承并且它起作用了。 FlaskForm 继承自 Form,默认启用和配置 csrf。
- https://flask-wtf.readthedocs.io/en/stable/form.html
- https://flask-wtf.readthedocs.io/en/stable/api.html#flask_wtf.FlaskForm
- https://wtforms.readthedocs.io/en/2.3.x/forms/
class AddressForm(Form):
address = StringField(label='Address', validators=[DataRequired()])
address2 = StringField(label='Address 2', validators=[Optional()])
city = StringField(label='City', validators=[DataRequired()])
county = SelectField(label='County', validators=[DataRequired()], choices=[], coerce=int)
class NameForm(Form):
first_name = StringField(label='First Name', validators=[DataRequired(), Length(min=2)] )
last_name = StringField(label='Last Name', validators=[DataRequired(), Length(min=2)] )