【问题标题】:FastAPI - can't access path parameters from middlewareFastAPI - 无法从中间件访问路径参数
【发布时间】:2020-11-03 19:56:51
【问题描述】:

我的典型路径是这样的

/user/{user_id}/resource/{resource_id}

我有一个验证方法,已经用 async python 写好了,像这样:

async def is_allowed(user_id: int, resource_id: int) -> bool

返回一个布尔值:如果用户可以访问资源,则返回 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}"}

记录的值为None。

【问题讨论】:

  • 就我所见,path_params 只有在 call_next() 方法返回后才可用。

标签: python-3.x fastapi


【解决方案1】:

您将无法使用中间件实现目标,因为中间件是在路由之前执行的。

因此,FastAPI/Starlette 不知道它将匹配哪个路径,也无法填充 path_params。

您将不得不使用不同的解决方案,例如将这些参数传递给 cookie、标头或查询参数,或者使用装饰器/依赖项。

参考:

https://github.com/encode/starlette/issues/230

https://fastapi.tiangolo.com/tutorial/middleware/#middleware

【讨论】:

    猜你喜欢
    • 2019-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-20
    • 1970-01-01
    • 2017-02-19
    • 1970-01-01
    相关资源
    最近更新 更多