FastAPI中@authorize装饰器触发422错误的修复方案问询
问题描述
现有FastAPI应用,向http://localhost:8000/login发送POST请求(请求体为{"username": "admin", "password": "password"})可获取有效JWT。将该JWT放入请求头后访问/items等端点时,移除@authorize(["admin"])装饰器接口可正常返回数据,但保留装饰器时会返回422 Unprocessable Entity错误:
{"detail": [{"loc": ["query", "kwargs"], "msg": "field required", "type": "value_error.missing"}]}
需修改哪部分代码才能让@authorize(["admin"])装饰器配合请求正常工作?
问题根源
错误出在authorization.py的authorize装饰器实现上:
- 被装饰的接口函数(如
get_item)包含路径参数,FastAPI会将这类参数作为位置参数传递给处理函数 - 原
wrapper函数将current_user=Depends(...)放在**kwargs之前,导致FastAPI无法正确解析路径参数,反而把**kwargs识别为必填查询参数,触发422错误
修改方案
调整authorization.py中authorize装饰器的wrapper函数参数定义,让它能正确接收原函数的所有参数,同时注入用户依赖:
# authorization.py def authorize(roles): def decorator(func): # 先接收原函数的位置参数和关键字参数,再注入current_user依赖 async def wrapper(*args, current_user=Depends(get_current_user), **kwargs): if current_user["role"] not in roles: raise HTTPException(status_code=403, detail="Unauthorized") # 将参数传递给原处理函数 return await func(*args, **kwargs) return wrapper return decorator
额外优化(可选,符合FastAPI最佳实践):给item_routes.py中get_item的item_id参数添加类型注解:
# item_routes.py @router.get("/items/{item_id}") @authorize(["admin"]) async def get_item(item_id: int): return {"item": item_id}
验证效果
重启FastAPI应用后,运行test.py,/items和/items/{item_id}端点将正常返回数据,不再出现422错误。
内容的提问来源于stack exchange,提问作者Anne Maier
相关产品推荐
相关产品推荐

