Iac*_*opo 4 python-3.x fastapi
我的典型路径是这样的
/user/{user_id}/resource/{resource_id}
Run Code Online (Sandbox Code Playgroud)
我有一个验证方法,已经用异步 python 编写,如下所示:
async def is_allowed(user_id: int, resource_id: int) -> bool
Run Code Online (Sandbox Code Playgroud)
返回一个布尔值:如果用户可以访问该资源,则返回 true,否则返回 false。
我想编写一个middleware调用is_allowed从路径中提取变量的程序。
我摆弄了一下,但找不到如何获取它们:我希望从request.path_params.
一个更完整的示例(根据@Marcelo Trylesinski 回答进行编辑):
import logging
from fastapi import FastAPI
from starlette.requests import Request
from starlette.responses import Response
app = FastAPI()
_logger = logging.getLogger()
_logger.setLevel(logging.DEBUG)
async def is_allowed(user_id, resource_id):
_logger.error(user_id)
_logger.error(resource_id)
return True
@app.middleware('http')
async def acl(request: Request, call_next):
user_id = request.path_params.get("user_id", None)
resource_id = request.path_params.get("resource_id", None)
allowed = await is_allowed(user_id, resource_id)
if not allowed:
return Response(status_code=403)
else:
return await call_next(request)
@app.get('/user/{user_id}/resource/{resource_id}')
async def my_handler(user_id: int, resource_id: int):
return {"what": f"Doing stuff with {user_id} on {resource_id}"}
Run Code Online (Sandbox Code Playgroud)
记录的值为None.
您将无法使用中间件来实现您的目标,因为中间件是在路由之前执行的。
因此 FastAPI/Starlette 不知道它将匹配哪个路径并且无法填充path_params.
您将不得不使用不同的解决方案,例如在 cookie、标头或查询参数上传递这些参数,或者使用装饰器/依赖项。
参考:
https://github.com/encode/starlette/issues/230
https://fastapi.tiangolo.com/tutorial/middleware/#middleware
| 归档时间: |
|
| 查看次数: |
3857 次 |
| 最近记录: |