FastAPI API Key 认证
FastAPI 作为现代化的 Python Web 框架,提供了开箱即用的安全认证组件,覆盖从简单的 API 密钥到复杂的 OAuth2 授权码流、JWT 认证等全场景。本系列教程将系统梳理 FastAPI 支持的所有认证方式,结合实战代码与最佳实践,帮助你根据业务场景选择最合适的认证方案。
前言:为什么接口必须做认证
在实际开发中,接口认证是后端服务的第一道安全防线,核心作用是:
- 身份校验:确认调用接口的用户 / 服务是合法的,拒绝非法访问;
- 权限控制:防止未授权用户操作敏感数据(如用户信息、订单、管理后台接口);
- 日志追溯:通过认证信息定位接口调用者,便于问题排查;
- 合规要求:满足数据安全规范(如隐私数据保护、企业安全标准)。
如果没有认证,你的接口会直接暴露在公网,任何人都能随意调用,极易导致数据泄露、恶意攻击、服务滥用等严重问题。
一、核心概念:认证与授权
很多新手会混淆认证(Authentication)和授权(Authorization),这是安全开发的基础概念:
- 认证(Authentication):验证**“你是谁”**→ 验证身份的合法性,常见方式包括账号密码、API 密钥、Token、第三方登录等。
- 授权(Authorization):你能做什么 → 基于认证后的身份验证是否有操作权限(比如:普通用户不能删除数据、管理员才能访问后台)。
本文重点讲认证(身份校验),后续篇章会讲解授权结合使用。
二、FastAPI 安全架构
FastAPI 认证核心工具(Depends / Security)
FastAPI 基于 Python 标准库和自身特性,提供了两个认证核心工具,所有认证方式都依赖它们实现:
Depends(依赖注入)
Depends 是 FastAPI 最核心的功能,用于提取公共逻辑、复用代码,认证逻辑本质就是「所有接口都需要执行的身份校验」,完美适配依赖注入。
- 作用:把认证逻辑封装成函数,所有接口通过
Depends自动调用,无需重复写校验代码; - 特性:支持全局、路由、单接口三级注入,灵活控制认证范围。
Security(安全工具)
fastapi.security 是 FastAPI 专门封装的认证工具包,内置了 API Key 等标准认证方案,遵循 OpenAPI 规范,自动生成交互式文档的认证入口。
- 核心类:
APIKeyQuery/APIKeyHeader/APIKeyCookie; - 特性:自动适配 Swagger UI 文档,支持一键填入认证信息测试接口。
FastAPI 认证方式
FastAPI 认证方式分为基础认证类和OAuth2 认证类两大体系:
| 组件类型 | 核心类 | 适用场景 |
|---|---|---|
| 基础认证 | APIKeyHeader/APIKeyQuery/APIKeyCookie | 简单 API 密钥认证、Swagger 手动输入 Token |
| 基础认证 | HTTPBasic/HTTPBearer | 基础账号密码认证、标准 Bearer Token 认证 |
| OAuth2 认证 | OAuth2Password``Bearer | 自身系统的账号密码登录、JWT 签发 |
| OAuth2 认证 | OAuth2AuthorizationCodeBearer | 第三方登录(GitHub、Gitee、微信、支付宝) |
| OAuth2 认证 | OAuth2ClientCredentials | 服务间调用(客户端凭证模式) |
三、API Key 认证原理
API Key 是一串预生成的唯一字符串(类似「接口密钥」),是服务端和客户端约定的身份凭证,属于最简单、最常用的无状态认证方式。
认证流程如下:
- 服务端提前给合法客户端分配一个固定的 API Key(存储在配置文件 / 数据库);
- 客户端调用接口时,必须携带这个 API Key;
- 服务端拦截请求,提取 API Key 并与本地存储的凭证对比;
- 校验通过 → 放行请求;校验失败 → 直接返回 401 错误。

四、API Key 三种传递方式:Header / Query / Cookie
FastAPI 在 fastapi.security 中提供了三个开箱即用的 API Key 认证类,分别对应三种不同的 API Key 传递方式:
| 类名 | 获取位置 | 示例 | 推荐度 |
|---|---|---|---|
| APIKeyHeader | 请求头(Header) | X-API-KEY: abc123 | ⭐⭐⭐⭐⭐(最常用、最安全) |
| APIKeyQuery | URL 查询参数 | /api/user?token=abc123 | ⭐⭐(会暴露在 URL 日志) |
| APIKeyCookie | Cookie | Cookie: token=abc123 | ⭐⭐⭐(适合 Web 前端) |
三者用法几乎完全一样,仅获取密钥的位置不同。
APIKeyHeader(Header 请求头)
APIKeyHeader 是 FastAPI 官方推荐、企业最常用的 API Key 认证方式,从 HTTP 请求头(Header)中提取密钥,安全性最高、最符合接口规范,自动对接 Swagger 文档。
配置参数
APIKeyHeader(
name: str, # 请求头的 key 名称(必须)
scheme_name: str = None, # OpenAPI 文档显示的安全方案名
description: str = None, # 文档描述
auto_error: bool = True # 未传密钥时是否自动返回 401
)
代码示例
-
使用
APIKeyHeader定义全局通用的 API Key 提取器,从自定义请求头X-API-Key中获取密钥:from fastapi.security import APIKeyHeader # 从请求头 X-API-Key 提取密钥 api_key_header = APIKeyHeader(name="X-API-Key")name用于告诉 FastAPI 从请求头的哪个字段获取 API Key(常用:X-API-Key、X-Token),即name="X-API-Key"要求客户端必须在请求头中携带X-API-Key字段才能访问受保护接口。 -
编写接口
/api/user/info,通过Depends(api_key_header)注入认证依赖,接口会先执行密钥校验,校验通过后才会执行业务逻辑:@app.get("/api/user/info", summary="需要 API Key 才能访问") def get_user_info(api_key: str = Depends(api_key_header)): return { "code": 200, "msg": "获取用户信息成功", "api_key": api_key[:6] + "****" # 脱敏展示 }接收到请求后,FastAPI 会先执行
api_key_header,api_key_header会自动从请求头里找X-API-Key:- 如果没有
X-API-Key请求头 → 直接返回 401,接口代码不执行 - 如果有 → 把密钥取出来,赋值给参数
api_key
- 如果没有
-
编写公开接口(无需任何认证),所有人可直接访问:
@app.get("/api/public/hello", summary="公开接口,无需认证") def public_hello(): return { "code": 200, "msg": "Hello, 公开接口" } -
启动应用:
uvicorn main:app --reload,访问 Swagger 文档:http://127.0.0.1:8000/docs:
-
点击右上角 Authorize 按钮:

-
输入合法的 API 密钥(如
sk_123456),点击授权:
-
之后访问所有接口会**自动携带****
X-API-Key**请求头,访问受保护接口时可正常获取数据;未授权则会抛异常:
APIKeyQuery(URL 参数)
APIKeyQuery 是 FastAPI 提供的 API Key 认证工具,用法与 APIKeyHeader 完全一致,仅密钥提取位置不同:它从 URL 查询参数 中提取 API Key,适合临时接口调试、内部简易接口场景。
配置参数
APIKeyQuery(
name: str, # 必填:URL 查询参数的键名(客户端需拼接 ?参数名=密钥)
scheme_name: str = None, # 可选:自定义认证方案名称(用于接口文档展示)
description: str = None, # 可选:认证方案描述(用于接口文档说明)
auto_error: bool = True # 可选:自动抛出异常,默认True(未携带密钥直接返回401)
)
代码示例
-
定义
APIKeyQuery提取规则:from fastapi.security import APIKeyQuery # 定义查询参数的 key 名称(客户端URL拼接 ?token=你的APIKey) api_key_query = APIKeyQuery(name="token", auto_error=False)name="api_key"告诉 FastAPI 从 URL 参数api_key中获取密钥。 -
编写测试接口,其中
/api/data接口只有带正确 URL 参数的请求才能访问:@app.get("/api/data", summary="URL 参数带 API Key") def get_data(api_key: str = Depends(api_key_query)): return {"code": 200, "msg": "通过 URL 参数认证成功"} @app.get("/api/public") def public_api(): return {"msg": "公开接口,无需 URL 参数"}FastApi 接收到请求后,
Depends(api_key_query)先检查 URL 里有没有?api_key=xxx:- 没有参数 → 直接 403,接口不运行
- 有参数 → 取出值赋值给
api_key,接口执行
APIKeyCookie(Cookie 提取)
APIKeyCookie 用于从请求 Cookie 中提取 API Key,是前后端一体 Web 项目的常用认证方式,浏览器会自动携带 Cookie 完成认证。
配置参数
APIKeyCookie(
name: str, # 必填:Cookie 的键名(客户端需携带 Cookie:键名=密钥)
scheme_name: str = None, # 可选:自定义认证方案名称(接口文档展示)
description: str = None, # 可选:认证方案描述(接口文档说明)
auto_error: bool = True # 可选:自动抛出异常,默认True(无Cookie直接返回401)
)
代码示例
-
定义提取规则,指定从 Cookie 字段
token中取密钥:from fastapi.security import APIKeyCookie # 定义:从 Cookie 的 token 字段中提取 API Key api_key_cookie = APIKeyCookie(name="token",auto_error=False) -
编写受保护接口,依赖注入
Depends(api_key_cookie):@app.get("/api/user/profile", summary="从 Cookie 取 API Key") def get_profile(api_key: str = Depends(api_key_cookie)): return {"code": 200, "msg": "通过 Cookie 认证成功"}请求到达接口时,
Depends(api_key_cookie)优先校验请求中是否携带token=xxxCookie:- 无
token=xxxCookie → 直接返回 401,拒绝访问; - 携带有效 Cookie → 自动提取密钥,赋值给
api_key变量,接口放行。
- 无
五、认证范围配置
FastAPI 认证支持三种灵活配置:
- 全局认证(所有接口默认需要认证)
- 路由分组认证(某一组接口统一认证,例如
/api/*) - 单接口认证(仅某个接口需要认证)
全局认证(全接口生效)
该方式项目所有接口开启认证,无需为每个接口单独配置,适用于全接口鉴权场景:
app = FastAPI(dependencies=[Depends(verify_api_key)])
路由分组认证(指定前缀生效)
使用 APIRouter 给某一类接口统一加认证,该路由下的所有接口开启认证,其他路由接口不受影响:
from fastapi import APIRouter
# 创建需要认证的路由
api_router = APIRouter(dependencies=[Depends(verify_api_key)])
# 该路由下所有接口自动认证
@api_router.get("/user/list")
async def user_list():
return {"msg": "该接口已自动通过API Key认证"}
# 把路由注册到 app
app.include_router(api_router, prefix="/api")
单接口认证(独立生效)
直接在接口上加依赖,仅当前接口生效:
@app.get("/order/info", dependencies=[Depends(verify_api_key)])
async def order_info():
return {"msg": "仅该接口需要认证"}
更多推荐
所有评论(0)