FastAPI oauth2-jwt-auth完全指南
📂 所属阶段:第四阶段 — 安全与认证(安全篇)
🔗 相关章节:FastAPIdependency-injection · FastAPIpassword-hashing-security
当你构建 API 时,身份认证是不可或缺的一环。本教程将带你从零开始,用 FastAPI 搭配 OAuth2 密码模式和 JWT,构建一个清晰、可扩展的鉴权系统。我们会覆盖最基本的快速实现,再慢慢演进到模块化、包含刷新令牌和权限控制的完整方案。
目录
为什么选择JWT认证?
传统Session认证 vs JWT认证
在 Web 开发中,常见的认证方式有两种:传统的服务端 Session 和今天的主题 JWT。它们在设计哲学上截然不同,我们用一个表格来对比:
简单来说,如果你的服务要部署成多个实例,或者前端是独立域名,JWT 会让你少踩很多坑。
JWT的核心价值
- 无状态 — 服务器不用记录谁登录了,每次请求自证身份。
- 可扩展 — 多个微服务实例可以独立验证同一个 Token,不用共享 Session。
- 跨域友好 — 前端可以随时把 Token 放在
Authorization头里发给不同域的后端。 - 自包含 — Token 内嵌了用户基本信息(如用户 ID、角色),减少查库次数。
- 标准化 — 遵循 RFC 7519,生态工具丰富。
项目依赖安装
先装好我们需要的库:
python-jose[cryptography]:生成和校验 JWT。passlib[bcrypt]+bcrypt:安全的密码哈希。python-multipart:解析 OAuth2 表单数据。
快速上手:核心实现
JWT结构简析
一个 JWT Token 看起来像一段乱码,实际上由三部分组成,用点号分隔:
- Header:包含算法类型
{"alg":"HS256","typ":"JWT"} - Payload:存放我们定义的声明,比如用户 ID、角色、过期时间等。注意:这部分只是 Base64 编码,不是加密,所以不能放敏感信息。
- Signature:将 Header 和 Payload 用密钥签名,防止被篡改。只有拥有密钥才能生成合法的签名。
最小化完整示例
下面是一个可以立刻跑起来的完整代码,它暴露了登录接口和需要认证的个人信息接口。你可以先复制、运行,感受流程,再慢慢拆解。
💡 运行测试
启动服务后,访问http://127.0.0.1:8000/docs可以在 Swagger UI 里直接测试:先执行/token获取 Token,再点击/users/me右侧的锁图标填入 Token,即可看到当前用户信息。
通过这个例子,你已经看到了 FastAPI 鉴权的核心套路:密码验证 → 签发 JWT → 依赖注入保护路由。下面我们把它拆分成更规范的模块结构,方便在实际项目中使用。
JWT工具模块
把所有 JWT 逻辑集中到一个管理器里,能减少重复代码,也方便将来更换算法或增加功能。
这个模块提供了三个核心能力:
- 密码哈希与校验:通过
verify_password和hash_password。 - 生成不同用途的 Token:
create_access_token用于短时间的访问令牌,create_refresh_token用于长期有效的刷新令牌。 - 统一的解码入口:
decode_token,如果 Token 过期或签名不对会直接抛出 401。
认证服务与路由
有了 JWT 工具,我们再封装一个简单的认证服务,把用户验证逻辑从路由里分离出来。
认证服务层
认证路由
现在编写专门的认证路由,暴露登录接口,并同时返回访问令牌和刷新令牌。
🧠 设计思路
- 访问令牌有效期短,降低泄露风险。
- 刷新令牌有效期长,前台可以静默刷新,用户无需频繁登录。
- 刷新令牌的
type字段可以用来区分用途,后面实现刷新接口时能进行校验。
依赖注入与受保护路由
FastAPI 的依赖注入是认证中最优雅的部分。我们编写几个不同粒度的依赖项,轻松实现“普通用户”和“管理员”的权限控制。
依赖注入实现
这几个依赖项像搭积木一样,一层层叠加验证逻辑,路由函数只需要声明需要的依赖即可。
受保护路由
现在你的路由可以自由组合不同的权限依赖,代码可读性和安全性都大幅提升。
安全最佳实践
功能跑通只是第一步,生产环境必须加上这些“防护盾”。
核心安全建议
- 全程 HTTPS — 绝不在 HTTP 链路上传递 Token,否则等于透明。
- 强密钥+轮换 — JWT 密钥至少 32 字节,定期更换,旧密钥可保留一段时间以便迁移。
- 短访问令牌 + 长刷新令牌 — 访问令牌 15~30 分钟过期,泄露后影响窗口小;用刷新令牌静默换取新访问令牌。
- 令牌黑名单 — 当用户登出或修改密码时,将当前 Token 的
jti加入 Redis 黑名单,网关层统一拦截。 - 密码安全 — 永远只存 bcrypt 哈希,不要记录明文,密码强度要求(长度、字符类型)在注册端校验。
- 速率限制 — 登录接口必须限制频率(例如 5次/分钟),防止暴力破解。
- 安全响应头 — 设置
X-Content-Type-Options: nosniff、X-Frame-Options: DENY等,增强整体防护。
企业级安全配置示例
将安全相关的配置集中管理,方便通过环境变量覆盖。
⚠️ 生产环境千万不要把密钥写在代码里,务必通过环境变量注入,而且建议使用非对称算法(如 RS256)来进一步提升安全性。
总结
通过本指南,我们构建了一个从简单到完善、可直接落地的 FastAPI 鉴权系统:
- 无状态设计 — JWT 自包含用户信息,完美适配多实例部署。
- 精细的权限控制 — 依赖注入让普通用户、活跃用户、管理员等权限划分一目了然。
- 安全的令牌管理 — 支持短时访问令牌、长时刷新令牌以及黑名单机制。
- 清晰的模块化架构 — JWT 管理器、认证服务、依赖项各自独立,易于测试和扩展。
💡 记住三个关键点:用 HTTPS 传输令牌;保持短有效期+刷新机制;做好速率限制和日志审计。这些是生产环境安全的基本盘。
🔗 扩展阅读

