flask_login 是一个 Flask 扩展,用于在 Flask web 应用中实现用户会话管理。它允许你跟踪哪些用户已经登录,并管理他们的登录状态。flask_login 提供了用户认证的基础结构,但具体的用户验证(如用户名和密码检查)和存储(如数据库)需要你自行实现。
以下是 flask_login 的一些主要特性和功能:
用户登录和注销:提供用户登录和注销的接口。
用户认证:通过装饰器(如 @login_required)确保只有已登录的用户才能访问特定的视图或路由。
用户会话管理:管理用户的登录状态,并提供一个安全的方式来跟踪用户会话。
用户信息:提供一个方式来获取当前登录用户的信息。
依赖
flask
flask_wtf
flask_sqlalchemy
captcha
werkzeug
效果
入口app
实现用户登录和注销的逻辑。这通常涉及到验证用户的凭据(如用户名和密码),并设置或清除用户的登录状态。
app.py
import random
import string
from flask import Flask, redirect, url_for, render_template, flash, session, Response
from flask_login import LoginManager, login_user, logout_user, login_required, current_user
from models import User, db
from LoginForm import LoginForm
from captcha.image import ImageCaptcha
login_manager = LoginManager()
image = ImageCaptcha()
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://user:pass@127.0.0.1/db"
app.config['SECRET_KEY'] = 'sd23rhewer'
login_manager.init_app(app)
login_manager.login_view = 'login'
db.init_app(app)
def generate_captcha():
"""
生成验证码文字
"""
characters = string.ascii_letters + string.digits
captcha = ''.join(random.choice(characters) for i in range(4))
return captcha
@login_manager.user_loader
def load_user(user_id):
"""
加载用户
"""
return User.query.get(int(user_id))
@app.route("/")
def index():
"""
前台首页
"""
return render_template('index.html')
@app.route('/dashboard')
@login_required
def dashboard():
"""
后台首页
"""
return render_template('dashboard.html', current_user=current_user)
@app.route('/login', methods=['GET', 'POST'])
def login():
"""
登录
"""
form = LoginForm()
if form.validate_on_submit():
captcha_session = session.get('capcha', '')
print(captcha_session, ' ', form.captcha.data)
if captcha_session.lower() != form.captcha.data.lower():
flash("验证码错误")
return redirect(url_for('login'))
user = User.query.filter_by(username=form.username.data).first()
if user is None or not user.check_password(form.password.data):
flash("用户名或密码错误")
return redirect(url_for('login'))
login_user(user, remember=True)
return redirect(url_for('dashboard'))
return render_template('login.html', form=form)
@app.route('/captcha_image', methods=['GET', 'POST'])
def captcha_image():
"""
验证码图片
"""
captcha = generate_captcha()
session['capcha'] = captcha
data = image.generate(captcha)
print(captcha)
return Response(data, mimetype="image/png")
@app.route('/logout', methods=['GET', 'POST'])
def logout():
"""
退出
"""
logout_user()
return redirect(url_for('index'))
表单
LoginForm.py
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, PasswordField
from wtforms.validators import DataRequired
class LoginForm(FlaskForm):
username = StringField('用户名', validators=[DataRequired('输入用户名')])
password = PasswordField('密码', validators=[DataRequired('输入密码')])
captcha = StringField('验证码', validators=[DataRequired('输入验证码')])
submit = SubmitField('提交')
数据库模型
在你的 Flask 应用中,你需要配置 flask_login,并定义一个用户类。这个用户类通常继承自 UserMixin,它提供了默认的用户属性和方法。
models.py
# coding: utf-8
from flask_login import UserMixin
from sqlalchemy import Column, DateTime, String, text
from sqlalchemy.dialects.mysql import INTEGER
from werkzeug.security import generate_password_hash, check_password_hash
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(engine_options={'pool_pre_ping': True})
class User(UserMixin, db.Model):
__tablename__ = 'xt_user'
id = Column(INTEGER(11), primary_key=True)
username = Column(String(50, 'utf8_unicode_ci'))
password = Column(String(1024, 'utf8_unicode_ci'))
create_at = Column(DateTime, server_default=text("CURRENT_TIMESTAMP"))
def set_password(self, password):
self.password = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password, password)
模板
templates/login.html
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<form method="POST">
{{ form.hidden_tag() }}
<p>
{{ form.username.label }}<br>
{{ form.username() }}
</p>
<p>
{{ form.password.label }}<br>
{{ form.password() }}
</p>
<p>
{{ form.captcha.label }}<br>
{{ form.captcha() }}
<img src="{{ url_for('captcha_image') }}" alt="Captcha" width="200", height="70">
</p>
<p>{{ form.submit() }}</p>
</form>
templates/dashboard.html
在视图函数中,你可以使用 current_user 对象来获取当前登录用户的信息。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>面板</title>
</head>
<body>
<p>您好,{{ current_user.username }} <a href="/logout">退出</a></a></p>
</body>
</html>
templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<p><a href="/login">登录</a></a></p>
</body>
</html>
初始化数据
from flask import Flask
from werkzeug.security import generate_password_hash
from models import db, User
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://user:pass@127.0.0.1/db"
db.init_app(app)
def init_data():
u1 = User(username='abc', password=generate_password_hash('123'))
db.session.add_all([u1])
db.session.commit()
with app.app_context() as context:
init_data()
参考
https://flask-login.readthedocs.io/en/latest/