七、登录功能的实现
七、1基本登录功能
和注册思路基本相同,用户输入邮箱和密码之后,去数据库中找是否存在改用户,诺存在即登录成功, 不存在返回错误提示。需要设置login.html和forms表单创建验证器,在user.py中创建login视图供向数据库提供数据。
设置login.html
{% extends "base.html" %}
{% block title %}知了问答-登录{% endblock %}
{% block head %}
{% endblock %}
{% block body %}
<div class="row mt-4">
<div class="col"></div>
<div class="col">
<form action="{{ url_for("user.login") }}" method="POST">
<div class="form-group">
<label for="exampleInputEmail1">邮箱</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" name="email">
</div>
<div class="form-group">
<label for="exampleInputPassword1">密码</label>
<input type="password" name="password" class="form-control" id="exampleInputPassword1">
</div>
{% for message in get_flashed_messages() %}
<div class="form-group">
<div class="text-danger">{{ message }}</div>
</div>
{% endfor %}
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">立即登录</button>
</div>
</form>
</div>
<div class="col"></div>
</div>
{% endblock %}
forms.py
import wtforms
from wtforms.validators import length,email,EqualTo,InputRequired
from models import EmailCaptchaModel,UserModel
class LoginForm(wtforms.Form):
email = wtforms.StringField(validators=[email()])
password = wtforms.StringField(validators=[length(min=6,max=20)])
class RegisterForm(wtforms.Form):
username = wtforms.StringField(validators=[length(min=3,max=20)])
email = wtforms.StringField(validators=[email()])
captcha = wtforms.StringField(validators=[length(min=4, max=4)])
password = wtforms.StringField(validators=[length(min=6,max=20)])
password_confirm = wtforms.StringField(validators=[EqualTo("password")])
def validate_captcha(self,field):
captcha = field.data
email = self.email.data
captcha_model = EmailCaptchaModel.query.filter_by(email=email).first()
if not captcha_model or captcha_model.captcha.lower() != captcha.lower():
raise wtforms.ValidationError("邮箱验证码错误!")
def validate_email(self,field):
email = field.data
user_model = UserModel.query.filter_by(email=email).first()
if user_model:
raise wtforms.ValidationError("邮箱已经存在!")
import random
import string
from flask import (Blueprint,
render_template,
request, redirect,
url_for,
jsonify,
session,
flash)
from blueprints.forms import RegisterForm,LoginForm
from exts import mail, db
from flask_mail import Message
from models import EmailCaptchaModel, UserModel
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash # 加密解密
bp = Blueprint("user", __name__, url_prefix="/user")
@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 user and check_password_hash(user.password, password):
session['user_id'] = user.id
return redirect("/")
else:
flash("邮箱和密码不匹配")
return redirect(url_for("user.login"))
else:
flash("邮箱或者密码格式错误")
return redirect(url_for("user.login"))
@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
# md5利用hash加密
hash_password = generate_password_hash(password)
user = UserModel(email=email, username=username, password=hash_password)
db.session.add(user)
db.session.commit()
return redirect(url_for("user.login"))
else:
return redirect(url_for("user.register"))
@bp.route("/captcha", methods=['POST'])
def get_captcha():
# GET,POST
email = request.form.get("email")
letters = string.ascii_letters + string.digits
captcha = "".join(random.sample(letters, 4))
if email:
message = Message(
subject="这是一封很有味道的邮件",
recipients=[email],
body=f"哈咯哈咯,您宝贵的码是:{captcha},请不要告诉任何人哦!"
)
mail.send(message)
captcha_model = EmailCaptchaModel.query.filter_by(email=email).first()
if captcha_model:
captcha_model.captcha = captcha
captcha_model.create_time = datetime.now()
db.session.commit()
else:
captcha_model = EmailCaptchaModel(email=email, captcha=captcha)
db.session.add(captcha_model)
db.session.commit()
print("captcha:", captcha)
# code: 200,成功的、正常的请求
return jsonify({"code": 200})
else:
# code:400,客户端错误
return jsonify({"code": 400, "message": "请先传递邮箱!"})
七、2登录错误信息提醒
这里进行最简单的两个提醒,
一个是密码和邮箱不匹配:即在数据库中找不到改数据就提示,不输入也进行改提示
第二个是邮箱或者验证码格式错误,这里是通过from.py表单来验证,不符合输入格式就提醒用户。