要解决这个问题,您需要定义表单的验证规则,生成和包含CSRF令牌,并进行适当的错误处理。下面是一个示例代码,展示了如何解决这个问题:
from flask import Flask, render_template, request, redirect, abort, make_response
import hashlib
import os
app = Flask(__name__)
# 生成CSRF令牌
def generate_csrf_token():
if '_csrf_token' not in session:
session['_csrf_token'] = hashlib.sha256(os.urandom(24)).hexdigest()
return session['_csrf_token']
# 验证CSRF令牌
def validate_csrf_token(csrf_token):
return csrf_token == session.pop('_csrf_token', None)
# 表单验证装饰器
def validate_form(form):
def decorator(view_func):
@wraps(view_func)
def wrapped_view(**kwargs):
if not validate_csrf_token(request.form.get('csrf_token')):
abort(403) # CSRF令牌验证失败,返回403错误
if not form.validate():
# 表单未通过验证,渲染带有错误信息的模板
return render_template('form.html', form=form)
return view_func(**kwargs)
return wrapped_view
return decorator
# 表单模型
class MyForm(FlaskForm):
name = StringField('Name', validators=[DataRequired()])
email = StringField('Email', validators=[Email()])
# 其他字段...
# 表单视图
@app.route('/form', methods=['GET', 'POST'])
@validate_form(MyForm())
def form_view():
if request.method == 'POST':
# 处理表单提交
# ...
return redirect('/success')
return render_template('form.html', form=MyForm())
# 成功页面
@app.route('/success')
def success_view():
return 'Form submitted successfully!'
if __name__ == '__main__':
app.secret_key = 'your_secret_key_here'
app.run()
在上面的示例中,我们定义了一个generate_csrf_token
函数来生成CSRF令牌,并将其存储在会话中。validate_csrf_token
函数用于验证令牌是否匹配。
在表单验证装饰器validate_form
中,我们首先验证CSRF令牌是否有效。如果令牌验证失败,我们返回403错误。然后,我们使用表单的validate
方法来验证其他字段。如果表单未通过验证,我们渲染带有错误信息的模板。
在表单视图form_view
中,我们使用validate_form
装饰器来应用表单验证。在POST请求中,我们处理表单提交并进行适当的重定向。在GET请求中,我们渲染带有表单的模板。
最后,我们定义了一个成功页面视图success_view
,用于显示表单提交成功的消息。
请根据您的具体需求进行适当的修改。