flask中wtforms表单验证问题

后端定义好表单验证规则后,前端按照表单验证规则去进行数据传入,但是总是提示验证失败,数据也是传入了解密之后的
前端的数据进了加密,后端也进行了解密,总是获取解密后 的数据。

报错截图

img

这个是wtforms表单规则

import wtforms
from wtforms.validators import Email, Length


class login_verify(wtforms.Form):
    username =wtforms.StringField(validators=[Length(min=3,max=10,message='用户名格式错误,需要3-10字')])
    password=wtforms.StringField(validators=[Length(min=5,max=15,message='密码格式错误,需要5-15字')])
    email=wtforms.StringField(validators=[Email(message='邮箱格式错误')])

后端代码

from flask import Blueprint, jsonify, request, render_template
from blueprints.verify import login_verify
from expand.CryptoJSencode import decrypt_AES

bp = Blueprint('login_click', __name__)


@bp.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        email = request.form['email']

        #调用AES解密前端数据
        username1 = decrypt_AES(username)
        password1 = decrypt_AES(password)
        email1 = decrypt_AES(email)

        verify=login_verify(username=username1,password=password1,email=email1)
        print(verify.username.data)

        if verify.validate():
            print('成功')
            return jsonify({'code': 200, 'message': 'OK', 'data': 'null'})
        else:
            print(verify.errors)
            return jsonify({'code': 200, 'message':' 失败', 'data': 'null'})
        
    return render_template('login.html')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=1145, debug=True)

AES解密代码

from Crypto.Cipher import AES
import base64

"""三方扩展,解密前端加密的数据"""

key = 'ThisIsASecretKey'
iv = 'ThisIsASecretKey'

def decrypt_AES(data):
    cipher = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv.encode('utf-8'))
    decrypted_data = cipher.decrypt(base64.b64decode(data))
    return decrypted_data.decode('utf-8').rstrip('\0') # 解密结果需要去除末尾的空字符

前端表单代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>login</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }

        body{
            background: url(../static/img/login/background-login.png);
            background-size: 100% auto;
            background-repeat:no-repeat ;
        }

       .setlogin {
            text-align: center;
            margin-top: 20% ;
       }

       .container .inputsubmit{
        width: 10%;
        margin: 0 auto;
       }

       .container .getdata{
        width: 30%;
        margin: 0 auto;
       }

       .text{
        font-size: 5rem;
        color: black;
       }

    </style>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.3/css/bootstrap.css" rel="stylesheet">
</head>
<body>
    <div class="container">
        <form  class="setlogin" method="post">
            <label for="title" class="text">登录</label>
            <input type="text" name="username" placeholder="请输入用户名" id="username" class="form-control getdata"><br>
            <input type="password" name="password" placeholder="请输入密码" id="password" class="form-control getdata" ><br>
            <input type="text" name="email" placeholder="邮箱" id="email" class="form-control getdata" ><br>
            <input type="submit"  id="one" value="登录/注册" class="form-control inputsubmit">
        </form>
    </div>

    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.3/js/bootstrap.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>

    <script>
        let one=document.getElementById('one')
        let username=document.getElementById('username')
        let password=document.getElementById('password')
        let email=document.getElementById('email')
        const key = CryptoJS.enc.Utf8.parse('ThisIsASecretKey')
        const iv = CryptoJS.enc.Utf8.parse('ThisIsASecretKey')
        one.onclick=function(event){
            event.preventDefault()
            let usernameAES = CryptoJS.AES.encrypt(username.value, key, { iv: iv }).toString()
            let passwordAES = CryptoJS.AES.encrypt(password.value, key, { iv: iv }).toString()
            let emailAES = CryptoJS.AES.encrypt(email.value, key, { iv: iv }).toString()

            $.ajax({
                url:'/login',
                type:'POST',
                data:{"username":usernameAES,"password":passwordAES,"email":emailAES},
                success:function(result){
                    alert(result.message)
                },
                error:function(){
                    alert('失败')
                }
            })
        }
    </script>
</body>
</html>

  • 这篇博客: flask框架的使用中的 十一、WTForms实现表单验证 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • forms - app - html 三件套

    forms.py

    from wtforms import Form, StringField, PasswordField, SubmitField
    from wtforms.validators import DataRequired, Length
    
    
    class LoginForm(Form):
        username = StringField(label='用户名', validators=[
            DataRequired('请填写用户名'),
            Length(min=6, max=50, message='用户名长度在6-50个字符之间')
        ])
        password = PasswordField(label='密码', validators=[
            DataRequired('请填写密码'),
            Length(min=6, max=50, message='密码在6-50')
        ])
        submit = SubmitField(label='提交')
    

    app.py

    from flask import Flask, render_template, request
    from forms import LoginForm
    
    app = Flask(__name__)
    app.debug = True
    
    
    @app.route('/', methods=['GET', 'POST'])
    def login():
        form = LoginForm(request.form)  # request.form是用户提交的表单内容
        if request.method == 'POST' and form.validate():
            pass
        return render_template('login.html', form=form)
    
    
    if __name__ == '__main__':
        app.run()
    

    templates中login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>login</title>
    </head>
    
    <body>
    <form action="" method="post">
        <div>
            {{ form.username.label }}
            {{ form.username }}
            {% for error in form.username.errors %}
                {{ error }}
            {% endfor %}
        </div>
        <div>
            {{ form.password.label }}
            {{ form.password }}
            {% for error in form.password.errors %}
                {{ error }}
            {% endfor %}
        </div>
        {{ form.submit }}
    </form>
    </body>
    </html>
    
  • 您还可以看一下 黄勇老师的2022版-Flask零基础到项目实战-学完可就业课程中的 23-wtforms表单验证小节, 巩固相关知识点