Flask-Principal 权限管理实战:从安装到角色控制
Flask-Principal 是 Flask 框架中用于处理权限管理的扩展。它通过 Identity(身份)、Needs(需求)和 Permission(权限)等核心组件,实现细粒度的访问控制。本文将通过实例分析,展示如何安装配置、定义角色、监听身份信号并实现基于角色的权限拦截。
Flask-Principal 核心组件与原理
Flask-Principal 的主要组件包括 Identity、Needs、Permission 和 IdentityContext。理解这些组件是正确使用该扩展的基础:
- Identity(身份):代表当前用户,负责存储和加载每个请求的身份信息,包含用户拥有的访问权限。
- Needs(需求):访问控制的最小粒度,代表具体的权限参数,例如“管理用户”或“编辑帖子”。
- Permission(权限):由一个或多个 Needs 组成,用于判断用户是否拥有执行某操作的资格。
- IdentityContext:针对特定权限的上下文,可用作上下文管理器或装饰器。
安装与初始化
首先,通过 pip 安装 Flask-Principal:
pip install flask-principal在 Flask 应用中初始化 Principal 实例:
from flask_principal import Principal
principal = Principal()
principal.init_app(app)定义角色与权限控制
我们需要定义角色常量,并创建基于角色的权限对象。以下代码定义了普通用户(NORMAL)和管理员(ADMIN)角色,并创建了一个仅允许 Admin 执行的权限:
from flask-principal import Permission,RoleNeed
from functools import wraps
# 定义相关角色
NORMAL = "NORMAL"
ADMIN = "ADMIN"
ROLES = (
("NORMAL","普通用户"),
("ADMIN","管理员")
)
# 创建仅允许 Admin 的权限
admin_permission = Permission(RoleNeed(ADMIN))
def admin_authority(func):
@wraps(func)
def decorated_view(*args,**kwargs):
if admin_permission.can():
return func(*args,**kwargs)
else:
return "非Admin用户"
return decorated_view用户模型与登录集成
结合 Flask-Login 和 SQLAlchemy 定义用户模型,并实现用户加载回调。注意,这里使用 ChoiceType 存储角色:
from app import login_manager
from app.db import Base,engine,session
from sqlalchemy import Column,String,Integer,create_engine
from sqlalchemy_utils.types.choice import ChoiceType
from flask_login import UserMixin
from permissions import ADMIN,ROLES
class User(Base,UserMixin):
__tablename__ = "user"
id = Column(Integer,primary_key=True)
user = Column(String(16))
password = Column(String(16))
roles = Column(ChoiceType(ROLES),default=ADMIN)
@login_manager.user_loaded
def user_loaded(id):
return session.query(User).filter_by(id=id).first()
Base.metadata.create_all(engine)登录流程与信号发送
在登录接口中,验证用户凭据后调用 Flask-Login 的 login_user,并发送 identity_changed 信号以触发权限加载:
from app import app
from flask import request
from flask_login import login_user
from flask_principal import current_app,identity_changed,Identity
from userinfo import User
from app.db import session
@app.route("/login",methods=["POST"])
def login():
user = request.form.get("user",None)
password = request.form.get("password",None)
if not user or not password:
...
user = session.query(User).filter_by(user=user,password=password).first()
if not user:
...
# 登录
login_user(user)
# 发送信号,载入用户权限
identity_changed.send(current_app._get_current_object(),identity=Identity(user.id))
return ...监听身份信号并加载权限
通过 identity_loaded 信号监听器,将当前用户的 ID 和角色添加到 Identity 的 provides 集合中,从而完成权限加载:
from flask_login import current_user
from flask_principal import identity_loaded,UserNeed,RoleNeed
@identity_loaded.connect_via(app)
def on_identity_loaded(sendder,identity):
identity.user = current_user
if hasattr(current_user,"id"):
identity.provides.add(UserNeed(current_user.id))
if hasattr(current_user,"roles"):
identity.provides.add(RoleNeed(current_user.roles.code))应用权限控制
最后,在需要保护的路由上使用自定义的 admin_authority 装饰器,实现只有 Admin 权限用户才能操作删除用户:
from app import app
from permission import admin_authority
@app.route("/delete_user",methods=["POST"])
@admin_authority
def delete_user():
...以上就是 Flask-Principal 基本用法与权限控制实例的详细内容,更多关于 Flask 权限管理、Python Web 开发、Flask-Principal 配置的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













