Flask实战开发——问答平台(五)用户注册与登录

Flask实战开发——问答平台(五)用户注册与登录_第1张图片

一、注册信息校验

1、使用表单验证  (flask-wtf )

pip install flask-wtf

 2、在蓝图buleprints文件下新建forms.py文件

import wtforms
from wtforms.validators import Email, Length, EqualTo, InputRequired
from models import UserModel, EmailCaptchaModel
from exts import db

# 注册表单Form:主要就是用来验证前端提交的数据是否符合要求
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", message="两次密码不一致!")])

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

    # 2. 验证码是否正确
    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="邮箱或验证码错误!")
        else:
            # todo:可以删掉captcha_model
            db.session.delete(captcha_model)
            db.session.commit()

3、auth.py  注册请求

from .forms import RegisterForm
from werkzeug.security import generate_password_hash
# GET:从服务器上获取数据
# POST:将客户端的数据提交给服务器
@bp.route("/register", methods=['GET', 'POST'])
def register():
    if request.method == 'GET':
        return render_template("register.html")
    else:
        # 验证用户提交的邮箱和验证码是否对应且正确
        # 表单验证:flask-wtf: wtforms
        form = RegisterForm(request.form)   #调用registerfrom表单验证
        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(form.errors)
            return redirect(url_for("auth.register"))

二、登录信息校验

Flask实战开发——问答平台(五)用户注册与登录_第2张图片

1、登录页面表单校验 LoginForm

class LoginForm(wtforms.Form):
    email = wtforms.StringField(validators=[Email(message="邮箱格式错误!")])
    password = wtforms.StringField(validators=[Length(min=6, max=20, message="密码格式错误!")])

2、auth.py   登录请求

from flask import Blueprint, render_template, jsonify, redirect, url_for, session
from exts import mail, db
from flask_mail import Message
from flask import request
import string
import random
from models import EmailCaptchaModel
from .forms import RegisterForm, LoginForm
from models import UserModel
from werkzeug.security import generate_password_hash, check_password_hash
@bp.route("/login", methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template("login.html")
    else:
        form = LoginForm(request.form)
        if form.validate():
            email = form.email.data
            password = form.password.data
            user = UserModel.query.filter_by(email=email).first()
            if not user:
                print("邮箱在数据库中不存在!")
                return redirect(url_for("auth.login"))
            if check_password_hash(user.password, password):
                # Cookie是服务器发送到用户本地浏览器并保存的一小段文本信息,它可以在用户后续访问中被浏览器携带并返回至服务器,从而实现状态管理或者数据存储的功能。
                # cookie中不适合存储太多的数据,只适合存储少量的数据
                # cookie一般用来存放登录授权的东西
                # flask中的session,是经过加密后存储在cookie中的
                session['user_id'] = user.id
                return redirect("/")   #登录成功进入首页
            else:
                print("密码错误!")
                return redirect(url_for("auth.login"))
        else:
            print(form.errors)
            return redirect(url_for("auth.login"))

3、设置密钥 SECRET_KEY

在Flask中,会话是一种机制,允许在多个请求之间存储用户特定的数据。为了确保会话的安全性,Flask使用了一个签名机制来验证会话数据的完整性。这个签名机制需要一个密钥,即SECRET_KEY。

config.py

SECRET_KEY = "asdfasdfjasdfjasd;lf"  #随意打的字符串 SECRET_KEY是Flask应用程序中的一个配置变量,用于设置一个密钥,用于保护会话和签名。

三、定义钩子函数

钩子函数是一种在特定事件或系统消息触发时自动被调用的函数

app.py

它在每个请求之前执行。它的作用是从会话中获取用户ID,然后根据用户ID查询用户信息,并将用户信息存储在全局变量g中。这样,在整个请求处理过程中,可以通过访问g.user来获取当前登录的用户信息。如果用户未登录(即session中没有user_id),则将g.user设置为None。

# before_request/ before_first_request/ after_request
# hook
@app.before_request
def my_before_request():
    user_id = session.get("user_id")
    if user_id:
        user = UserModel.query.get(user_id)
        setattr(g, "user", user)
    else:
        setattr(g, "user", None)

 把用户信息放在上下文处理器中

这段代码是一个Flask应用程序中的上下文处理器,它返回一个字典,其中包含一个键值对"user": g.user。上下文处理器的作用是在模板中自动注入一些变量,使得这些变量可以在所有模板中使用。在这个例子中,它将g.user注入到模板中,这样在模板中可以直接访问当前登录的用户信息。

@app.context_processor
def my_context_processor():
    return {"user": g.user}

四、登录状态和非登录状态之间页面切换

登录账号后首页显示用户名,退出登录则用户名消失

base.html

定义退出登录视图函数

auth.py 

@bp.route("/logout")
def logout():
    session.clear()  #清空信息
    return redirect("/")  #跳转回首页

上一章节:Flask实战开发——问答平台(四)邮箱验证-CSDN博客

下一章节:Flask实战开发——问答平台(六)发布问答-CSDN博客 

Flask实战开发——问答平台(五)用户注册与登录_第3张图片

你可能感兴趣的:(Flask从入门到实践,flask,python,后端)