如何为FastAPI路由创建可捕获路径参数值的装饰器?
FastAPI:用装饰器获取路径参数并做权限校验
可行方案:三层嵌套装饰器动态获取参数
因为装饰器在定义阶段无法拿到运行时的请求参数,所以需要通过三层嵌套的装饰器,在请求处理阶段动态提取路径参数值:
1. 实现装饰器
from fastapi import HTTPException def allowed_perm(required_perm: str, param_name: str): def decorator(func): async def wrapper(*args, **kwargs): # 从路由函数的关键字参数中提取目标路径参数 param_value = kwargs.get(param_name) if param_value is None: raise HTTPException(status_code=400, detail=f"缺少路径参数 {param_name}") # 此处添加权限校验逻辑 # 示例:校验当前用户是否拥有对该workflowID的WF_ADMIN权限 # current_user = kwargs.get("current_user") # 若用户信息通过Depends注入到路由参数 # if not has_permission(current_user, required_perm, param_value): # raise HTTPException(status_code=403, detail="无权限操作此工作流") # 执行原路由函数 return await func(*args, **kwargs) return wrapper return decorator
2. 路由上的使用方式
注意传入装饰器的是参数名字符串('workflowID'),而非变量,因为装饰器定义阶段无法获取运行时的参数值:
@router.put("/{workflowID}", response_model=WorkflowResponse) @allowed_perm('WF_ADMIN', 'workflowID') async def update_workflow_endpoint( workflowID: int, workflow: WorkflowUpdateRequest, db: AsyncSession = Depends(get_db) ): # 原有业务逻辑 ...
原理说明
FastAPI会将解析后的路径参数、请求体等以关键字参数的形式传入路由函数,装饰器的wrapper函数可以直接通过kwargs字典获取到这些运行时的参数值(比如请求/5时,kwargs['workflowID']的值就是5)。
补充说明
虽然装饰器能实现需求,但FastAPI官方更推荐使用依赖项处理权限校验——依赖项支持更灵活的复用、嵌套,还能更好地和FastAPI的异步机制、请求上下文集成。如果你的权限逻辑需要在多个路由中复用,优先考虑依赖项方案。
内容的提问来源于stack exchange,提问作者Ouroboros
相关产品推荐
相关产品推荐

