Flask(七)用户认证与权限管理

在 Web 应用中,用户认证(Authentication)和权限管理(Authorization)是至关重要的功能。Flask 提供了多种方式来实现用户身份验证,包括 Flask-Login 进行用户会话管理,Flask-WTF 处理表单,以及 Flask-Bcrypt 进行密码加密。

本章内容:

  • Flask-Login 介绍
  • Flask-WTF 处理用户注册
  • Flask-Bcrypt 进行密码加密
  • 用户登录与会话管理
  • 访问控制与权限管理
  • 基于角色的权限控制(RBAC)
  • API 认证(JWT)

7.1 安装所需扩展

pip install flask-login flask-wtf flask-bcrypt flask-sqlalchemy

7.2 配置 Flask-Login

app.py 里初始化 Flask-Login:

python 复制代码
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager

app = Flask(__name__)

app.config['SECRET_KEY'] = 'your_secret_key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'

db = SQLAlchemy(app)

login_manager = LoginManager(app)

login_manager.login_view = 'login'  # 指定未登录时跳转的视图

login_manager.login_message = "请先登录才能访问该页面!"

7.3 定义用户模型

python 复制代码
from flask_login import UserMixin

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)

    username = db.Column(db.String(20), unique=True, nullable=False)

    email = db.Column(db.String(120), unique=True, nullable=False)

    password = db.Column(db.String(60), nullable=False)

    def __repr__(self):
        return f"User('{self.username}', '{self.email}')"

说明:

  • UserMixin 提供 is_authenticated, is_active, is_anonymous, get_id() 等方法。

7.4 加载用户

Flask-Login 需要一个用户加载函数,在 app.py 中添加:

python 复制代码
from flask_login import LoginManager
from models import User

@login_manager.user_loaderdef load_user(user_id):
    return User.query.get(int(user_id))

7.5 用户注册

7.5.1 创建注册表单

python 复制代码
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Email, EqualTo

class RegistrationForm(FlaskForm):
    username = StringField('用户名', validators=[DataRequired()])

    email = StringField('邮箱', validators=[DataRequired(), Email()])

    password = PasswordField('密码', validators=[DataRequired()])

    confirm_password = PasswordField('确认密码', validators=[DataRequired(), EqualTo('password')])

    submit = SubmitField('注册')

7.5.2 处理用户注册

routes.py 里添加视图:

python 复制代码
from flask import render_template, redirect, flash, url_for
from app import app, db
from models import User
from forms import RegistrationForm
from flask_bcrypt import Bcrypt

bcrypt = Bcrypt(app)

@app.route('/register', methods=['GET', 'POST'])
def register():
    form = RegistrationForm()

    if form.validate_on_submit():
        hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')

        user = User(username=form.username.data, email=form.email.data, password=hashed_password)

        db.session.add(user)

        db.session.commit()

        flash('账号注册成功!请登录', 'success')

        return redirect(url_for('login'))

    return render_template('register.html', form=form)

7.5.3 创建register.html

html 复制代码
<form method="POST">

    {{ form.hidden_tag() }}

    <p>{{ form.username.label }} {{ form.username }}</p>

    <p>{{ form.email.label }} {{ form.email }}</p>

    <p>{{ form.password.label }} {{ form.password }}</p>

    <p>{{ form.confirm_password.label }} {{ form.confirm_password }}</p>

    <p>{{ form.submit }}</p>
</form>

7.6 用户登录与登出

7.6.1 创建登录表单

python 复制代码
from wtforms.validators import Length

class LoginForm(FlaskForm):
    email = StringField('邮箱', validators=[DataRequired(), Email()])

    password = PasswordField('密码', validators=[DataRequired(), Length(min=6, max=20)])

    submit = SubmitField('登录')

7.6.2 处理用户登录

python 复制代码
from flask_login import login_user

@app.route('/login', methods=['GET', 'POST'])
def login():

    form = LoginForm()

    if form.validate_on_submit():

        user = User.query.filter_by(email=form.email.data).first()

        if user and bcrypt.check_password_hash(user.password, form.password.data):

            login_user(user)

            flash('登录成功!', 'success')

            return redirect(url_for('dashboard'))

        else:

            flash('登录失败,请检查邮箱和密码!', 'danger')

    return render_template('login.html', form=form)

7.6.3 处理用户登出

python 复制代码
from flask_login import logout_user

@app.route('/logout')
def logout():

    logout_user()

    flash('你已退出登录', 'info')

    return redirect(url_for('login'))

7.7 访问控制

Flask-Login 提供 @login_required 装饰器,限制未登录用户访问特定页面。

python 复制代码
from flask_login import login_required

@app.route('/dashboard')
@login_required
def dashboard():

    return "欢迎来到用户面板!"

7.8 角色权限管理(RBAC)

7.8.1 修改 User模型,添加** role字段**

python 复制代码
class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)

    username = db.Column(db.String(20), unique=True, nullable=False)

    email = db.Column(db.String(120), unique=True, nullable=False)

    password = db.Column(db.String(60), nullable=False)

    role = db.Column(db.String(10), nullable=False, default='user')  # 角色字段

7.8.2 创建权限管理装饰器

python 复制代码
from functools import wraps
from flask import abort
from flask_login import current_user

def role_required(role):

    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):

            if current_user.role != role:

                abort(403)  # 权限不足

            return f(*args, **kwargs)

        return decorated_function

    return decorator

7.8.3 应用到管理员页面

python 复制代码
@app.route('/admin')
@login_required
@role_required('admin')
def admin_panel():

    return "管理员面板"

7.9 API 认证(JWT)

使用 Flask-JWT-Extended 进行 API 认证。

7.9.1 安装 Flask-JWT-Extended

pip install flask-jwt-extended

7.9.2 配置 JWT

python 复制代码
from flask_jwt_extended import JWTManager

app.config['JWT_SECRET_KEY'] = 'supersecretkey'

jwt = JWTManager(app)

7.9.3 生成 JWT 令牌

python 复制代码
from flask_jwt_extended import create_access_token

@app.route('/token', methods=['POST'])
def login_jwt():

    user = User.query.filter_by(email=request.json.get("email")).first()

    if user and bcrypt.check_password_hash(user.password, request.json.get("password")):

        access_token = create_access_token(identity=user.id)

        return jsonify(access_token=access_token)

    return jsonify(msg="用户名或密码错误"), 401

7.10 结语

本章介绍了 Flask 用户认证的完整流程:

  • 用户注册
  • 登录/登出
  • 访问控制
  • 基于角色的权限管理
  • API 认证

下一章将介绍 Flask 的异步任务与后台处理。

相关推荐
程序员清风1 小时前
贝壳一面:年轻代回收频率太高,如何定位?
java·后端·面试
摆烂z1 小时前
Jupyter Notebook的交互式开发环境方便py开发
ide·python·jupyter
考虑考虑1 小时前
Java实现字节转bcd编码
java·后端·java ee
AAA修煤气灶刘哥2 小时前
ES 聚合爽到飞起!从分桶到 Java 实操,再也不用翻烂文档
后端·elasticsearch·面试
爱读源码的大都督2 小时前
Java已死?别慌,看我如何用Java手写一个Qwen Code Agent,拯救Java
java·人工智能·后端
星辰大海的精灵3 小时前
SpringBoot与Quartz整合,实现订单自动取消功能
java·后端·算法
天天摸鱼的java工程师3 小时前
RestTemplate 如何优化连接池?—— 八年 Java 开发的踩坑与优化指南
java·后端
一乐小哥3 小时前
一口气同步10年豆瓣记录———豆瓣书影音同步 Notion分享 🚀
后端·python
LSTM973 小时前
如何使用C#实现Excel和CSV互转:基于Spire.XLS for .NET的专业指南
后端
三十_3 小时前
【NestJS】构建可复用的数据存储模块 - 动态模块
前端·后端·nestjs