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

如何为FastAPI除/和/health外的所有端点启用API Key认证?

针对FastAPI批量API Key认证(排除指定端点)的最优方案

方案1:改进中间件,添加路径白名单

直接在原有中间件逻辑中加入路径判断,仅对非白名单路径校验API Key,无需调整应用结构,改动成本最低。

示例代码:

from fastapi import FastAPI, HTTPException, Request
from your_settings_module import settings  # 替换为你的配置模块

app = FastAPI()

# 定义无需认证的路径白名单
WHITELIST_PATHS = {"/", "/health"}

def is_production():
    # 替换为你的生产环境判断逻辑,比如读取环境变量
    return True

@app.middleware("http")
async def validate_api_key(request: Request, call_next):
    path = request.url.path
    # 仅在生产环境且路径不在白名单时校验
    if is_production() and path not in WHITELIST_PATHS:
        api_key = request.headers.get("X-API-KEY")
        if not api_key or api_key != settings.API_KEY:
            raise HTTPException(status_code=401, detail="Unauthorized")
    response = await call_next(request)
    return response

# 白名单端点示例
@app.get("/")
async def root():
    return {"message": "Hello World"}

@app.get("/health")
async def health_check():
    return {"status": "healthy"}

# 需要认证的端点示例
@app.get("/protected/data")
async def get_protected_data():
    return {"data": "sensitive information"}

方案2:用APIRouter批量绑定认证依赖

将所有需要认证的端点统一注册到一个APIRouter,给该路由添加全局认证依赖;白名单端点直接注册到主应用,既避免逐个加依赖,又能清晰划分认证范围。

示例代码:

from fastapi import FastAPI, Depends, HTTPException, Request
from your_settings_module import settings

app = FastAPI()
# 创建专门用于受保护端点的路由
protected_router = APIRouter()

async def api_key_auth(request: Request):
    if is_production():
        api_key = request.headers.get("X-API-KEY")
        if not api_key or api_key != settings.API_KEY:
            raise HTTPException(status_code=401, detail="Unauthorized")

# 给整个路由添加全局认证依赖
protected_router.dependencies.append(Depends(api_key_auth))

# 白名单端点直接注册到主应用
@app.get("/")
async def root():
    return {"message": "Hello World"}

@app.get("/health")
async def health_check():
    return {"status": "healthy"}

# 受保护端点注册到专用路由
@protected_router.get("/protected/data")
async def get_protected_data():
    return {"data": "sensitive information"}

@protected_router.post("/protected/create")
async def create_protected_item(item: dict):
    return {"created": item}

# 将路由挂载到主应用(空前缀实现同层级访问)
app.include_router(protected_router)

方案选择建议

  • 若端点数量少、不想拆分路由,优先选方案1,代码改动最小;
  • 若端点较多、需要清晰划分认证边界,优先选方案2,结构更易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 20:03:22