You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI如何将include_router的dependencies返回值传递给子路由

FastAPI 路由级依赖返回值透传解决方案

你遇到的问题本质是:FastAPI 中通过include_router的dependencies参数传入的全局路由依赖,仅会执行依赖的校验逻辑,返回值会被默认丢弃,无法直接被下层路径函数接收。以下是两种生产环境常用的实现方案:


方案1:请求上下文存储(推荐)

通过 FastAPI 提供的Request对象的state属性存储 JWT 解码结果,子路由按需取值即可,无需修改原有路由挂载的逻辑,也不会重复执行依赖校验。

步骤1:修改依赖函数,把 payload 存入请求上下文

修改main.py中的authenticate_and_decode_JWT函数:

from typing import Optional
from jose import jwt
# 新增导入Request
from fastapi import FastAPI, Depends, Header, HTTPException, status, Request
from jose.exceptions import JWTError

from routers import books

app = FastAPI()

def authenticate_and_decode_JWT(request: Request, x_token: str = Header(None)):
    # 补充参数校验,避免空token时split报错
    if not x_token or not x_token.startswith("Bearer "):
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
    try:
        payload = jwt.decode(x_token.split(' ')[1], 'secret key', algorithms=['HS256'])
        # 把解码结果存入请求上下文,全链路可访问
        request.state.jwt_payload = payload
        return payload
    except JWTError:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)

# 原有路由挂载逻辑无需修改
app.include_router(
    books.router,
    prefix="/books",
    dependencies=[Depends(authenticate_and_decode_JWT)], 
)

@app.get("/")
def read_root():
    return {"Hello": "World"}

步骤2:子路由中获取 payload

可以直接注入Request对象取值,也可以封装单独的取值依赖简化代码:

直接取值写法(routers/books.py)

from fastapi import APIRouter, Request

router = APIRouter()

@router.get('/')
def get_book(request: Request):
    payload = request.state.jwt_payload
    # 直接使用payload中的用户信息即可
    pass

@router.post('/')
def create_book(request: Request):
    payload = request.state.jwt_payload
    pass

封装取值依赖写法(更简洁)

首先在公共依赖文件(或main.py)中封装取值逻辑:

def get_jwt_payload(request: Request) -> dict:
    return request.state.jwt_payload

之后子路由接口直接注入该依赖即可:

from fastapi import APIRouter, Depends
# 导入封装的取值依赖
from main import get_jwt_payload

router = APIRouter()

@router.get('/')
def get_book(payload: dict = Depends(get_jwt_payload)):
    # 直接使用payload
    pass

@router.post('/')
def create_book(payload: dict = Depends(get_jwt_payload)):
    pass

方案2:子路由层面声明依赖

如果不想用请求上下文存储,也可以直接把JWT校验依赖作为子路由路径函数的通用参数,FastAPI会自动复用依赖的执行结果,不会重复校验:

# routers/books.py
from fastapi import APIRouter, Depends
from main import authenticate_and_decode_JWT

router = APIRouter()

@router.get('/')
def get_book(payload: dict = Depends(authenticate_and_decode_JWT)):
    pass

@router.post('/')
def create_book(payload: dict = Depends(authenticate_and_decode_JWT)):
    pass

这种写法下可以把include_router中声明的依赖去掉,避免重复声明。适合仅部分子路由接口需要用到payload的场景。


内容的提问来源于stack exchange,提问作者neilZon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 22:15:07