32. FastAPI 依赖注入_路径级
给某一个接口附加前置检查
本篇的“路径级”指某个路径操作装饰器上的 dependencies=[Depends(...)],不是 Path 参数验证。适合只检查能否访问、不需要把返回值传给路由的情况。
完整示例
python
import os
from secrets import compare_digest
from typing import Annotated
from fastapi import Depends, FastAPI, Header, HTTPException
app = FastAPI()
def verify_api_key(
x_api_key: Annotated[str | None, Header()] = None,
):
expected = os.getenv("STUDY_API_KEY")
if not expected:
raise HTTPException(503, "服务尚未配置 API Key")
if x_api_key is None or not compare_digest(x_api_key, expected):
raise HTTPException(401, "API Key 无效")
@app.get("/public")
def public():
return {"message": "公开信息"}
@app.get("/private", dependencies=[Depends(verify_api_key)])
def private():
return {"message": "通过检查"}保存为 main.py。设置环境变量再启动:
powershell
$env:STUDY_API_KEY = 'local-study-key'
uv run uvicorn main:app --reload另一个终端调用:
powershell
curl.exe -i http://127.0.0.1:8000/private -H "X-API-Key: local-study-key"不带头访问 /public 仍成功;访问 /private 得到 401;传正确头成功。Header 默认把变量名里的下划线转换成连字符,所以 x_api_key 对应 X-API-Key。
不使用返回值,与需要返回值
装饰器中的依赖会执行,但结果不会成为路由参数。若依赖返回当前用户且路由要使用用户 ID,就应在函数参数上写 current_user: Annotated[User, Depends(get_current_user)]。
这两种方式都绑定到一个路径操作,只是是否接收结果不同。可以同时使用,但别为了“更安全”重复写同一套检查。
多个依赖及错误处理
dependencies=[Depends(check_a), Depends(check_b)] 可添加多项检查。若 B 必须使用 A 的结果,应写嵌套依赖明确关系,而不是仅把它们并排摆放。检查失败抛出 HTTPException 会中止后续业务执行。
API Key 适合部分服务调用场景;用户登录、过期、角色管理应使用更完整的认证设计。示例值只用于本地练习,实际配置不要硬编码或写入 URL。这里使用 compare_digest 比较 ASCII Key;若允许非 ASCII 凭据,应先按明确编码转字节再比较。
练习:添加一个单独受保护的 POST 操作;比较装饰器依赖与参数依赖在函数签名和返回值使用上的差异。