FastApi中使用Enum实现安全端点的多权限组合控制方案问询
基于枚举角色的FastAPI权限控制解决方案
首先明确你之前写法无效的原因:permission_admin or permission_manager是Python的逻辑或运算,它会直接返回第一个"真值"的函数对象(也就是permission_admin),FastAPI的Depends只会执行这一个函数,完全不会去检查permission_manager,自然达不到"管理员或经理均可访问"的效果。
下面是几种专业且灵活的实现方式:
1. 通用权限依赖函数(推荐)
创建一个可复用的权限检查函数,接收允许的角色列表作为参数,无需为每种组合单独写函数:
步骤1:定义角色枚举和获取当前用户角色的函数
from enum import Enum from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer # 定义角色枚举 class Role(str, Enum): USER = "user" ADMIN = "admin" MANAGER = "manager" # 模拟解码JWT获取当前用户角色的函数(实际项目替换为真实JWT解码逻辑) oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") def get_current_user_role(token: str = Depends(oauth2_scheme)) -> Role: # 实际中从token解析用户角色并返回,此处为模拟逻辑 return Role.MANAGER
步骤2:编写通用权限检查函数
def has_permission(allowed_roles: list[Role]): def permission_checker(current_role: Role = Depends(get_current_user_role)): if current_role not in allowed_roles: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="无访问权限" ) return True return permission_checker
步骤3:在接口中使用
from fastapi import FastAPI app = FastAPI() # 管理员或经理均可访问的接口 @app.get("/users") def fetch_users(is_auth: bool = Depends(has_permission([Role.ADMIN, Role.MANAGER]))): return {"data": ["user1", "user2", "user3"]} # 仅管理员可访问的接口 @app.post("/users") def create_user(is_auth: bool = Depends(has_permission([Role.ADMIN]))): return {"message": "用户创建成功"}
这种方式支持任意角色组合,复用性极强,无需编写重复的组合权限函数。
2. 逻辑组合的依赖工厂类
如果希望保留原有的permission_admin、permission_manager等单独权限函数,可以用工厂类实现"任意满足"的逻辑:
步骤1:保留单独的权限函数
def permission_admin(current_role: Role = Depends(get_current_user_role)): if current_role != Role.ADMIN: raise HTTPException(status_code=403, detail="仅管理员可访问") return True def permission_manager(current_role: Role = Depends(get_current_user_role)): if current_role != Role.MANAGER: raise HTTPException(status_code=403, detail="仅经理可访问") return True
步骤2:编写任意权限组合类
class AnyPermission: def __init__(self, *permissions): self.permissions = permissions def __call__(self): def checker(): for perm in self.permissions: try: # 执行权限检查,通过则直接返回 perm() return True except HTTPException: # 该权限不满足,继续检查下一个 continue # 所有权限都不满足,抛出403 raise HTTPException(status_code=403, detail="无访问权限") return checker()
步骤3:在接口中使用
@app.get("/users") def fetch_users(is_auth: bool = Depends(AnyPermission(permission_admin, permission_manager))): return {"data": ["user1", "user2", "user3"]}
这种方式适合已有多个独立权限函数的场景,通过组合类快速实现"或"逻辑。
内容的提问来源于stack exchange,提问作者janluk
相关产品推荐
相关产品推荐

