[python][flask]Flask-Principal 使用详解

Flask-Principal 是一个专为 Flask 应用设计的身份管理和权限控制扩展。它能够帮助开发者轻松实现用户身份验证和权限管理,从而提升应用的安全性和用户体验。该项目最初由 Ali Afshar 开发,现已成为 Pallets 社区生态系统的一部分,由社区共同维护。

1. 安装 Flask-Principal

首先,需要安装 Flask-Principal。可以通过以下命令安装:

python 复制代码
pip install flask-principal
2. 基本配置

在 Flask 应用中配置 Flask-Principal,初始化扩展并定义权限

python 复制代码
from flask import Flask
from flask_principal import Principal, Permission, RoleNeed

app = Flask(__name__)
app.secret_key = 'your_secret_key'  # 用于会话管理

# 初始化 Flask-Principal
principals = Principal(app)

# 定义权限
admin_permission = Permission(RoleNeed('admin'))
3. 定义用户模型

假设你已经有一个用户模型,用户模型中包含角色信息。例如:

python 复制代码
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    roles = db.relationship('Role', secondary='user_roles')

class Role(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=True)

class UserRole(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    role_id = db.Column(db.Integer, db.ForeignKey('role.id'))
4. 身份加载器

定义一个身份加载器,用于在用户登录时加载用户的角色和权限

python 复制代码
from flask_login import current_user
from flask_principal import identity_loaded, RoleNeed, UserNeed

@identity_loaded.connect_via(app)
def on_identity_loaded(sender, identity):
    # 设置当前用户对象
    identity.user = current_user

    # 添加用户 ID
    if hasattr(current_user, 'id'):
        identity.provides.add(UserNeed(current_user.id))

    # 添加用户角色
    if hasattr(current_user, 'roles'):
        for role in current_user.roles:
            identity.provides.add(RoleNeed(role.name))
5. 保护视图

使用 Permission 对象保护视图,确保只有具有相应权限的用户才能访问

python 复制代码
@app.route('/admin')
@admin_permission.require(http_exception=403)
def admin_dashboard():
    return "Welcome to the admin dashboard!"

也可以使用上下文管理器来保护视图中的部分代码

python 复制代码
@app.route('/articles')
def articles():
    with admin_permission.require():
        return "Only admins can see this"
6. 登录与注销

在用户登录时,发送身份更改信号

python 复制代码
from flask_principal import Identity, identity_changed

@app.route('/login', methods=['GET', 'POST'])
def login():
    # 假设有一个登录表单
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user and user.check_password(form.password.data):
            login_user(user)
            identity_changed.send(app, identity=Identity(user.id))
            return redirect(url_for('admin_dashboard'))
    return render_template('login.html', form=form)

在用户注销时,清除身份信息

python 复制代码
from flask_principal import AnonymousIdentity

@app.route('/logout')
def logout():
    logout_user()
    for key in ('identity.name', 'identity.auth_type'):
        session.pop(key, None)
    identity_changed.send(app, identity=AnonymousIdentity())
    return redirect(url_for('login'))
7. 自定义权限

除了基于角色的权限,还可以定义更复杂的权限需求。例如,定义一个基于特定操作的权限

python 复制代码
edit_permission = Permission(RoleNeed('editor'))

@app.route('/edit_article')
@edit_permission.require(http_exception=403)
def edit_article():
    return "Only editors can edit articles"
8. 总结

Flask-Principal 提供了一种灵活的方式来实现基于角色和权限的访问控制。通过定义权限、加载用户身份和保护视图,可以轻松实现复杂的授权逻辑。结合 Flask-Login,可以实现完整的用户认证和授权系统。

希望这些信息能帮助你更好地使用 Flask-Principal!

相关推荐
will_net6 分钟前
apollo 站点部署&C#接入
开发语言·c#·apollo
威哥爱编程27 分钟前
Python 智能体开发实战 05:一问教材内容它就编?先把答案从你自己的资料里检索出来
python·agent
java_prinln33 分钟前
RAG 面试题介绍
python·agent
威哥爱编程35 分钟前
Python 智能体开发实战 06:一个函数里塞了八百行?用状态机把批改流程拆成能回退的步骤
python·agent
晗夜未央44 分钟前
任务队列反复失败,先分清重试、阻塞和结果待核对
开发语言·javascript
熊猫钓鱼>_>1 小时前
四种书签,一条时间线:一个读书 App 的记忆颗粒与它的边界案例【鸿蒙心迹】
开发语言·华为·ai编程·harmonyos·鸿蒙·openharmony·鸿蒙pc
努力努力再努力wz1 小时前
【Lua 入门系列】Lua 函数深入理解:函数对象、多返回值、可变参数、闭包、递归与尾调用优化
开发语言·lua
Patrick在香港1 小时前
一个斜杠,把毫秒变成十几秒
android·数据库·python·性能优化·正则表达式·回溯·redos
2601_967980112 小时前
Python 初学者必备的常用内置函数
python·编程语言·内置函数·初学者·常用函数
OnlineProxy2 小时前
移动应用数据爬取:通过模拟器与流量嗅探对 API 进行逆向工程
爬虫·python·httpx