flask_login 是一个 Flask 扩展,用于在 Flask web 应用中实现用户会话管理。它允许你跟踪哪些用户已经登录,并管理他们的登录状态。flask_login 提供了用户认证的基础结构,但具体的用户验证(如用户名和密码检查)和存储(如数据库)需要你自行实现。
以下是 flask_login 的一些主要特性和功能:
用户登录和注销:提供用户登录和注销的接口。
用户认证:通过装饰器(如 @login_required)确保只有已登录的用户才能访问特定的视图或路由。
用户会话管理:管理用户的登录状态,并提供一个安全的方式来跟踪用户会话。
用户信息:提供一个方式来获取当前登录用户的信息。
依赖
flask
flask_wtf
flask_sqlalchemy
captcha
werkzeug
效果
入口app
实现用户登录和注销的逻辑。这通常涉及到验证用户的凭据(如用户名和密码),并设置或清除用户的登录状态。
app.py
import random
import stringfrom 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 ImageCaptchalogin_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.digitscaptcha = ''.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'] = captchadata = 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 DataRequiredclass 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 SQLAlchemydb = 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_hashfrom models import db, Userapp = 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/