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 的异步任务与后台处理。

相关推荐
小哲慢慢来2 分钟前
解决auto_gptq安装问题
python
奔跑草-4 分钟前
【服务端】使用conda虚拟环境部署Django项目
python·django·conda
ai大师5 分钟前
给聊天机器人装“短期记忆“:Flask版实现指南
后端·python·gpt·flask·oneapi·中转api·apikey
galileo20166 分钟前
rust服务应用开发框架
后端·rust
moz与京4 小时前
[附C++,JS,Python题解] Leetcode 面试150题(10)——轮转数组
c++·python·leetcode
什码情况5 小时前
回文时间 - 携程机试真题题解
数据结构·python·算法·华为od·机试
Alfadi联盟 萧瑶5 小时前
Python-Django入手
开发语言·python·django
codingandsleeping6 小时前
浏览器的缓存机制
前端·后端
漠北尘-Gavin6 小时前
【Python3.12.9安装llama-cpp-python遇到编译报错问题解决】
python·llama
追逐时光者6 小时前
面试官问:你知道 C# 单例模式有哪几种常用的实现方式?
后端·.net