表单不验证,没有错误。包含CSRF令牌

时间:2019-05-01 19:01:29

标签: python flask flask-wtforms

我正在使用带有一些烧瓶wtforms的烧瓶应用程序。当我获得表格时,它们从未被验证,但是表格错误为空。我可能是什么问题?

我知道我没有的一个常见问题是包含csrf_token。我包含了它,并且在我的网页加载时可以看到它在html中呈现。但是仍然没有验证

这是我正在渲染的html文件

<div class="forms center">
    <h1>Account Details</h1>
    <h2>Update Email Address</h2>
    <form id="update-email" action={{ url_for('crud.update_email') }} method="post">
        {{ email_form.hidden_tag() }}
        <div><input type="text" name="new-email" placeholder="new email address" value=""></div>
        <div><input type="submit" name="submit" value="Update Email Address"></div>
    </form>
    <h2>Update Password</h2>
    <form id="update-password" action={{ url_for('crud.update_password') }} method="post">
        {{ password_form.hidden_tag() }}
        <div><input type="password" name="old-password" placeholder="enter old password" id="old-password" value=""></div>
        <div><input type="password" name="new-password" placeholder="enter new password" id="new-password" value=""></div>
        <div><input type="password" name="retypepassword" placeholder="retype password" id="retypepassword" value=""></div>
        <div><input type="submit" name="submit" id="submit" value="Update Password"></div>
    </form>
</div>

它正在此路线中呈现

@views.route('/account-details', methods=['POST', 'GET'])
@login_required
def account_details():
    email_form = UpdateEmailForm()
    password_form = UpdatePasswordForm()
    return render_template('account-details.html', email_form=email_form, password_form=password_form)

提交更新密码表单到此处

@crud.route('/update-password', methods=['POST'])
def update_password():
    form = UpdatePasswordForm()
    old_password = request.form.get('old-password')
    new_password = pbkdf2_sha256.hash(request.form.get('new-password'))
    userid = session.get('userid')
    user_dao = UserDao()

    if form.validate_on_submit():
        user_dao.update_password(userid, new_password)
        return jsonify({"success": True})
    return jsonify({"success": False})

这是我正在使用的表单类

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, validators
from wtforms.validators import DataRequired, Email, EqualTo, Length, ValidationError

class UpdatePasswordForm(FlaskForm):
    oldpassword = PasswordField('old-password', [DataRequired()])
    newpassword = PasswordField('new-password', [DataRequired(), EqualTo('retypepassword'), Length(min=6)])
    retypepassword = PasswordField('retypepassword', [DataRequired()])

在浏览器中的“网络”选项卡上,它正在发布请求中发送预期的结果,如果我在后端进行检查,它会收到预期的一切。不幸的是,表单仍然无法通过验证,因此我希望它与我对wtforms不了解的事情有关

谢谢!

2 个答案:

答案 0 :(得分:2)

我认为替代答案是正确的。我有很多FlaskForm,但我没有通过请求。

相反,我认为您的错误可能出在您的命名约定中。您的班级字段名称为:

'oldpassword' 'newpassword' etc..

但是您的HTML元素ID和名称为:

'old-password' 'new-password'

即表单不知道要解析什么。对齐您的姓名。

答案 1 :(得分:1)

在POST中,您需要将请求数据传递到以下表单中:

form = UpdatePasswordForm(request.POST)

您无需从request.form获取值,并且可以在进行更新之前进行验证:

@crud.route('/update-password', methods=['POST'])
def update_password():
    form = UpdatePasswordForm(request.POST)

    if form.validate_on_submit():
        userid = session.get('userid')
        user_dao = UserDao()

        new_password = pbkdf2_sha256.hash(form.newpassword.data)
        user_dao.update_password(userid, new_password)
        return jsonify({"success": True})
    return jsonify({"success": False})

编辑:我强烈建议阅读WTForms crash course(以及更多内容),以更好地了解WTForms的功能-这非常有用。