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

Python中FastAPI认证422错误及请求传递问题解决

解决FastAPI认证中的422错误与Request对象传递问题

问题根源

  1. Request对象未正确注入:路径操作函数test中声明的request参数未指定类型为FastAPI的Request,导致FastAPI将其视为查询参数,而请求中未传递该参数,因此返回422错误。
  2. 认证模块兼容问题:认证代码使用了Django REST Framework(DRF)的APIException和request.META,但FastAPI基于Starlette框架,其Request对象的属性和异常处理机制与DRF不兼容。

修复步骤

1. 修正主代码中的Request对象注入

从fastapi导入Request并明确声明参数类型,让FastAPI自动注入请求对象:

from typing import Union
import requests
import uvicorn
from auth import authenticate
from fastapi import FastAPI, Request  # 导入Request类
import boto3
import json

app = FastAPI()

client = boto3.client('eks')
boto3.set_stream_logger('')


@app.get("/test")
def test(request: Request):  # 指定参数类型为Request
    token = authenticate(request)
    print("test")
    return {"message": "认证成功", "token_data": token}

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

2. 适配认证模块到FastAPI环境

替换DRF相关依赖,使用FastAPI的HTTPException处理错误,并适配Starlette的Request对象:

import jwt
from general.config import constants
from fastapi import HTTPException  # 替换DRF的APIException
from starlette.requests import Request

jwtPrivateKey = constants.PRIVATE_KEY

def authenticate(request: Request):
    try:
        # 从Request.headers获取Authorization头,替代DRF的request.META
        auth_header_value = request.headers.get("Authorization", "")
        if auth_header_value:
            if len(auth_header_value.split(" ", 1)) == 2:
                authmeth, auth = auth_header_value.split(" ", 1)
                if authmeth.lower() not in ["bearer", "basic"]:
                    raise HTTPException(status_code=401, detail="Token必须为Bearer或Basic类型")
                
                try:
                    token_value = jwt.decode(
                        jwt=auth, key=jwtPrivateKey, algorithms=['HS256']
                    )
                    return token_value
                except jwt.DecodeError:
                    raise HTTPException(status_code=401, detail="无效的Token")
                except jwt.ExpiredSignatureError:
                    raise HTTPException(status_code=401, detail="Token已过期")
            else:
                raise HTTPException(status_code=401, detail="Authorization头格式无效")
        else:
            raise HTTPException(status_code=401, detail="未提供Authorization头")
    except HTTPException:
        raise

3. (可选)使用FastAPI依赖注入优化认证逻辑

将认证逻辑封装为依赖项,可在多个接口中复用,更符合FastAPI最佳实践:

# 在auth.py中新增依赖函数
from fastapi import Depends

def get_current_user(request: Request = Depends()):
    return authenticate(request)

# 主代码中使用依赖
@app.get("/test")
def test(current_user: dict = Depends(get_current_user)):
    print("test")
    return {"message": "认证成功", "用户信息": current_user}

关键说明

  • FastAPI的Request对象来自Starlette,获取请求头需使用request.headers,而非DRF的request.META。
  • 必须使用FastAPI的HTTPException抛出错误,框架会自动将其转换为符合HTTP规范的响应(包含正确状态码和错误信息)。
  • 依赖注入是FastAPI实现认证的推荐方式,代码更简洁且易于复用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 04:10:40