在flask中如何快速的实现登录注册注销功能,以及登录状态验证等功能? flask的扩展库中有Flask-Login库就可快速的实现以上的功能,实现起来是非常的便利。
安装Flask-Login
pip install flask-login
定义模板
基础页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
{% block title %}
{% endblock %}
</title>
{% block js %}
{% endblock %}
{% block css %}
{% endblock %}
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
注册页面
对form表单的映射
{% extends 'base.html' %}
{% block content %}
<form action="" method="post">
{{ form.csrf_token }}
{{ form.username.label }} : {{ form.username }}
{% if form.errors.username %}
{{ form.errors.username[0] }}
{% endif %}<br>
{{ form.password.label }} : {{ form.password }}<br>
{{ form.password2.label }} : {{ form.password2 }}
{% if form.errors.password2 %}
{{ form.errors.password2[0] }}
{% endif %}<br>
{{ form.submit() }}
</form>
{% endblock %}
登录页面
{% extends 'base.html' %}
{% block content %}
<form action="" method="post">
username:<input type="text" name="username"><br>
password:<input type="text" name="password"><br>
<input type="submit" value="登录">
</form>
{% endblock %}
主页
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>我是首页!</p>
<p>{{ current_user.username }}</p>
<img src="/static/media/{{ current_user.icons }}">
<form action="" method="post" enctype="multipart/form-data">
头像:<input type="file" name="icons">
<input type="submit" value="提交">
</form>
</body>
</html>
定义User模型
from flask_login import UserMixin
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class User(UserMixin, db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(10), unique=True, nullable=False)
password = db.Column(db.String(128), nullable=False)
icons = db.Column(db.String(100),nullable=True)
连接数据库
在启动文件manager.py文件中引入应用文件夹中模型中SQLAlchemy的对象db,与应用绑定,并进行初始化,和相关配置。
from user.modles import db
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:root@127.0.0.1:3306/f_login'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
对login的应用
配置
app.config['SECRET_KEY'] = 'secret_key'
# 未登录状态跳转地址
login_manager.login_view = 'user.login'
login_manager.init_app(app)
应用
import os
from flask_login import LoginManager, login_user, logout_user, login_required, current_user
from flask import Blueprint, request, render_template, redirect, url_for
from werkzeug.security import generate_password_hash, check_password_hash
from user.forms import UserRegisterForm
from user.modles import db, User
from utils.setting import UPLOAD_DIR
user_blueprint = Blueprint('user', __name__)
login_manager = LoginManager()
@user_blueprint.route('/create_db/')
def create_db():
db.create_all()
return '创建成功'
@user_blueprint.route('/register/', methods=['GET', 'POST'])
def register():
form = UserRegisterForm()
if request.method == 'GET':
return render_template('register.html', form=form)
if request.method == 'POST':
# 验证提交的字段信息
if form.validate():
username = form.username.data
password = form.password.data
# 实现注册,保存用户信息到User模型中
user = User()
user.username = username
user.password = generate_password_hash(password)
db.session.add(user)
db.session.commit()
return redirect(url_for('user.login'))
else:
# 验证失败,from.errors中存在错误信息
return render_template('register.html', form=form)
@login_manager.user_loader
def load_user(user_id):
return User.query.get(user_id)
@user_blueprint.route('/login/', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
if not all([username, password]):
return render_template('login.html')
user = User.query.filter(User.username == username).first()
if user:
# 获取到用户,进行密码判断
if check_password_hash(user.password, password):
login_user(user)
return redirect(url_for('user.index'))
else:
error = '密码错误'
return render_template('login.html', error=error)
else:
error = '该用户尚未注册,请先行注册后在进行登录!'
return render_template('login.html', error=error)
@user_blueprint.route('/index/',methods=['GET','POST'])
@login_required
def index():
if request.method == 'GET':
return render_template('index.html')
if request.method == 'POST':
# 获取
icons = request.files.get('icons')
# 保存
file_path = os.path.join(UPLOAD_DIR,icons.filename)
icons.save(file_path)
user = current_user
user.icons = os.path.join('upload',icons.filename)
db.session.add(user)
db.session.commit()
return redirect(url_for('user.index'))