Flask大作业

本文详细介绍了网站的登录流程,包括前端JavaScript实现的输入有效性校验,确保用户名和密码长度在指定范围内,以及后端使用WTForms进行数据校验,检查用户是否存在和密码是否匹配。在用户信息校验成功后,会跳转至个人主页,而如果密码错误或用户未注册,则会显示相应错误信息或引导用户进行注册。整个过程结合了前端和后端的验证机制,确保了用户登录的安全性。
摘要由CSDN通过智能技术生成

1 网站使用流程

所设计的网站页面跳转关系如下图所示:

2 登陆校验

2.1 前端JS输入有效性校验

HTML代码:

{% extends "base.html" %} <!--模板继承,父模板内容为顶栏与背景等网页统一布局-->

{% block title %}Login{% endblock %}  <!--子模版网页标题-->

{% block head %}
     <link rel="stylesheet" href="{{ url_for('static', filename='css/login.css') }}">
     <script src="{{ url_for('static', filename='jquery/jquery.3.6.min.js') }}"></script>
     <script src="{{ url_for('static', filename='js/login.js') }}"></script>
{% endblock %}

{% block content %}
    <form method="POST" name="loginform">  <!--登陆表单-->
        <div class="form-group">
            <div class="loginformlabel"><label>用户名</label></div>
                <input type="text" class="logininput" aria-describedby="emailHelp"
                    name="username" id="un1" onblur="logincheck1('#un1','#am1')" > 
                <!--用户名输入,失去焦点时触发JS校验事件“logincheck1”-->
                <div class="alarmmessage1" id="am1"></div> 
                <!--放置错误信息的提示的盒子,内容待JS校验后写入-->
        </div>
        <div class="form-group">
            <div class="loginformlabel"><label for="exampleInputPassword1">密码</label></div>
                <input type="password" name="password" class="logininput" id="exampleInputPassword1" onblur="logincheck2('#exampleInputPassword1','#am2')" >
                <!--密码输入,失去焦点时触发JS校验事件“logincheck2”-->
                <div class="alarmmessage2" id="am2"></div>
                <!--放置错误信息的提示的盒子,内容待JS校验后写入-->
        </div>
        <div class="form-group">
            <button type="submit" class="loginbutton">立即登录</button> <!--登录(提交表单)按钮-->
        </div>
    </form>
{% if lof_errors == '用户名或密码错误!' %} <!--后端校验内容-->
    <script type="text/javascript">alert("用户名或密码错误!")</script>
{% endif %}
{% endblock %}

JS代码:

//errSelector为对应的放置错误信息提示盒子
function switchValid(onOff,errSelector,message){ //控制错误信息内容的函数
    if(onOff == false){
        $(errSelector).text(message);  //若校验失败,将错误提示信息写入errSelector
    }
    else
    {
        $(errSelector).text(""); //若校验成功,错误信息内容为空
    }
}

//用户名输入有效性校验
function logincheck1(input,errSelector){
    var a = $(input).val(); //获取用户输入的用户名
    var str1 = a.toString();  //将其转换为字符串类型,以便检查长度
    if (str1.length<3 || str1.length>20){
        switchValid(false,errSelector,"用户名格式错误,长度应为3-20"); //校验失败,调用switchValid,传入校验结果与错误提示信息,将错误提示信息写入对应的提示盒子
        return false;
    } else{
        switchValid(true,errSelector); //校验成功,调用函数但不传入message
        return true;
    }
}

//密码输入有效性校验,与用户名的校验同理
function logincheck2(input,errSelector){
    var b = $(input).val();
    var str2 = b.toString();
    if (str2.length<6 || str2.length>20){
        switchValid(false,errSelector,"密码格式错误,长度应为6-20");
        return false;
    } else {
        switchValid(true, errSelector);
        return true;
    }
}

效果如图:

登录页:

正确输入用户名与密码:

用户名有效性校验失败:

用户名与密码有效性校验均失败:

2.2 后端用户信息校验

登陆页面视图函数:

@bp.route('/', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template("login.html")
    else: # 前端提交表单数据后进行验证
        form = LoginForm(request.form) # 后端输入有效性验证
        if form.validate(): # 后端有效性校验成功
            username = form.username.data # 获取输入的用户名和密码
            password = form.password.data
            user = UserModel.query.filter_by(username=username).first() # 首先在数据库中查找用户是否存在(已注册)
            if not user: # 查找不到用户,即用户不存在
                return redirect(url_for('auth.register')) #重定向到注册页面
            if check_password_hash(user.password, password): # 查找到了用户,检查密码是否正确
                session['user_id'] = user.id # 若密码正确,则获取用户相关信息
                return redirect("/index") #并重定向到个人主页
            else: # 密码不正确
                print("用户名或密码错误!")
                var1 = '用户名或密码错误!'
                return render_template("login.html", lof_errors=var1) # 返回错误信息到前端页面
        else: #后端有效性校验失败
            print(form.errors)
            return redirect(url_for("auth.login")) #重定向到登录页

后端输入有效性校验:

class LoginForm(wtforms.Form):
    username = wtforms.StringField(validators=[Length(min=3, max=20, message="用户名格式错误!")])
    password = wtforms.StringField(validators=[Length(min=6, max=20, message="密码格式错误!")])

后端用户信息校验后的不同情况如下讨论所示。

2.2.1 用户信息校验成功跳转到个人主页

个人主页前端代码:

{% extends "base.html" %}

{% block title %}Index{% endblock %}

{% block head %}
     <link rel="stylesheet" href="{{ url_for('static', filename='css/basecss.css') }}">
{% endblock %}

{% block content %}
    <div class="post">
        <div class="user"><img src="{{ url_for('static', filename='img/user1.jpg') }}" class="userimg">user1</div>
        <div class="postcontent"><img src="{{ url_for('static', filename='img/img1.jpg') }}" class="postimg"></div>
    </div>
    <div class="post">
        <div class="user"><img src="{{ url_for('static', filename='img/user2.jpg') }}" class="userimg">user2</div>
        <div class="postcontent"><img src="{{ url_for('static', filename='img/img2.jpg') }}" class="postimg"></div>
    </div>
    <div class="post">
        <div class="user"><img src="{{ url_for('static', filename='img/user3.jpg') }}" class="userimg">user3</div>
        <div class="postcontent"><img src="{{ url_for('static', filename='img/img3.jpg') }}" class="postimg"></div>
    </div>
{% endblock %}

个人主页视图函数:

@bp.route('/index')
def index():
    return render_template('index.html')

效果如下:

输入已注册的用户名与正确的密码:

跳转到个人主页:

2.2.2 用户存在但密码错误

后端反馈错误(仅截取相关部分代码):

            else: # 密码不正确
                print("用户名或密码错误!")
                var1 = '用户名或密码错误!'
                return render_template("login.html", lof_errors=var1) # 返回错误信息到前端页面

前端接受错误信息并显示(仅截取相关部分代码):

{% if lof_errors == '用户名或密码错误!' %} <!--后端校验内容-->
    <script type="text/javascript">alert("用户名或密码错误!")</script>
{% endif %}

效果如下:

输入已注册的用户名但错误的密码:

弹窗提示错误信息:

2.2.3 用户不存在(未注册)跳转到注册页

注册页面前端代码(HTML):

{% extends "base.html" %}

{% block title %}Register{% endblock %}

{% block head %}
    <link rel="stylesheet" href="{{ url_for('static', filename='css/register.css') }}">
    <script src="{{ url_for('static', filename='jquery/jquery.3.6.min.js') }}"></script>
    <script src="{{ url_for('static', filename='js/register.js') }}"></script>
{% endblock %}

{% block content %}
     <form method="POST">
           <div class="form-group">
               <div class="loginformlabel"><label>邮箱</label></div>
               <input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" name="email">
           </div>
           <div class="form-group">
               <div class="loginformlabel"><label>验证码</label></div>
               <div class="input-group">
                    <input type="text" id="yanzm" name="captcha">
                    <button class="btnyzm" type="button" id="captcha-btn">获取验证码</button>
               </div>
           </div>
           <div class="form-group">
               <div class="loginformlabel"><label>用户名</label></div>
                   <input type="text" class="form-control" name="username">
           </div>
           <div class="form-group">
               <div class="loginformlabel"><label>密码</label></div>
               <input type="password" class="form-control" id="exampleInputPassword1" name="password">
           </div>
           <div class="form-group">
               <div class="loginformlabel"><label>确认密码</label></div>
               <input type="password" class="form-control" name="password_confirm">
           </div>
           <button type="submit" class="registerbutton" id="regibtn">立即注册</button>
     </form>
{% endblock %}

注册页面视图函数:

@bp.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'GET':
        return render_template("register.html")
    else:
        form = RegisterForm(request.form) # 后端注册校验
        if form.validate(): # 校验成功,则将输入数据添加并同步到数据库
            email = form.email.data
            username = form.username.data
            password = form.password.data
            user = UserModel(email=email, username=username, password=generate_password_hash(password))
            db.session.add(user)
            db.session.commit()
            return redirect(url_for("auth.login")) # 注册成功,跳转到登录页登录
        else:
            print(type(form.errors['email'])) # 校验失败,需重新填写信息
            return redirect(url_for("auth.register"))

后端注册表单校验:

class RegisterForm(wtforms.Form):
    # 注册表单输入有效性验证
    email = wtforms.StringField(validators=[Email(message="邮箱格式错误!")])
    captcha = wtforms.StringField(validators=[Length(min=4, max=4, message="验证码格式错误!")])
    username = wtforms.StringField(validators=[Length(min=3, max=20, message="用户名格式错误!")])
    password = wtforms.StringField(validators=[Length(min=6, max=20, message="密码格式错误!")])
    password_confirm = wtforms.StringField(validators=[EqualTo("password")])

    # 验证邮箱是否已被注册
    def validate_email(self, field):
        email = field.data
        user = UserModel.query.filter_by(email=email).first()
        if user:
            raise wtforms.ValidationError(message="该邮箱已被注册!")

    # 验证输入的验证码是否正确
    def validate_captcha(self, field):
        captcha = field.data
        email = self.email.data
        captcha_model = EmailCaptchaModel.query.filter_by(email=email, captcha=captcha).first()
        if not captcha_model:
            raise wtforms.ValidationError(message="邮箱或验证码错误!")

验证码相关:

后端视图函数代码(发送验证码):

@bp.route('/captcha/email')
def get_email_captcha():
    email = request.args.get("email") # 获取输入的邮箱
    source = string.digits*4
    # 从source中随机取样,取四位
    captcha = random.sample(source, 4)
    captcha = "".join(captcha)  # 把随机生成的四位数的列表转换成字符串
    message = Message(subject="注册验证码", recipients=[email], body=f"您的验证码是{captcha}")
    mail.send(message) # 向邮箱发送验证码
    # 将邮箱与验证码信息添加到数据库中
    email_captcha = EmailCaptchaModel(email=email, captcha=captcha) 
    db.session.add(email_captcha)
    db.session.commit()
    print(captcha)
    return jsonify({"code": 200, "message": "", "data": None}) # 返回表示发送成功的状态码

前端“获取验证码”的JS代码:

$(function () {
     $("#captcha-btn").click(function (event) {  //按钮“获取验证码”的点击事件
        event.preventDefault(); 
        var email = $("#exampleInputEmail1").val(); //获取输入的邮箱
        $.ajax({   //发送验证码
            url: "/captcha/email?email="+email, 
            method: "GET",
            success: function (result){
                var code = result['code'];
                if(code == 200){  //检查状态码
                     alert("邮箱验证码发送成功!");
                }else{
                    alert(result['message']);
                }
            },
            fail: function(error){
                console.log(error);
            }
        })
    });
});

效果如下:

输入邮箱,点击按钮“获取验证码”:

邮箱收到验证码,并查看数据库的数据:

输入收到的验证码以及其它信息,点击“立即注册”:

注册成功,跳转到登录页。

查看数据库中用户信息表:

即已注册成功,注册功能实现。


以上即为本次作业的全部内容。✅

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值