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

FastAPI GET请求中aud字段被识别为请求体的解决方法

解决FastAPI GET请求中BaseModel被当作请求体解析的问题

你的问题在于直接将AccessClaims(继承自BaseModel)作为Depends()的参数,FastAPI会默认把这种BaseModel类型的依赖当作请求体模型处理,而GET请求并不支持请求体,因此才会试图从请求体中解析aud等字段。

核心解决方案:自定义JWT解析依赖函数

正确的做法是编写一个专门的依赖函数,负责从请求中提取并解析JWT令牌,验证后返回AccessClaims实例,而非直接将模型类传入Depends。

示例代码如下:

from jose import JWTError, jwt
from fastapi import Depends, HTTPException, status, APIRouter
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel, Optional, Union, List
import time

# 配置JWT参数(根据实际情况修改)
SECRET_KEY = "your-actual-secret-key"
ALGORITHM = "HS256"
OAUTH2_SCHEME = OAuth2PasswordBearer(tokenUrl="token")

router = APIRouter()

class JWTClaims(BaseModel):
    iat: int
    exp: int
    aud: Optional[Union[str, List[str]]]
    iss: str
    sub: str
    azp: str

class AccessClaims(JWTClaims):
    scope: str

async def get_validated_claims(token: str = Depends(OAUTH2_SCHEME)) -> AccessClaims:
    # 定义凭证验证失败的异常
    credentials_error = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="无法验证凭证",
        headers={"WWW-Authenticate": "Bearer"},
    )
    
    try:
        # 解码JWT令牌,可根据需求添加audience验证等逻辑
        payload = jwt.decode(
            token,
            SECRET_KEY,
            algorithms=[ALGORITHM],
            # 如果需要验证audience,取消下面注释并填写对应值
            # audience="your-audience-value"
        )
        # 将解码后的载荷转换为AccessClaims实例
        claims = AccessClaims(**payload)
        
        # 可选:添加令牌过期检查
        current_timestamp = int(time.time())
        if claims.exp < current_timestamp:
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="令牌已过期")
        
    except JWTError:
        raise credentials_error
    
    return claims

@router.get("/client")
async def get_user_client(claims: AccessClaims = Depends(get_validated_claims)):
    # 这里可以正常使用claims中的字段
    return {"client_info": f"用户ID: {claims.sub}, 权限范围: {claims.scope}"}

原理说明

  • FastAPI对Depends()的处理逻辑:当传入的是一个类(如AccessClaims),它会尝试调用该类的构造方法,默认从请求体中获取数据填充字段;而传入自定义函数时,会执行函数内的逻辑,返回的结果才会赋值给参数。
  • 自定义依赖函数中,我们通过OAuth2PasswordBearer从请求头的Authorization字段提取JWT令牌,解码后转换为AccessClaims模型,同时添加了异常处理确保凭证有效性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 02:05:25