JWT 到底怎么用?一篇讲透 + FastAPI 鉴权实战

今天这篇文章,目标很明确:

帮你把 JWT 从"听过"变成"会用",并给你一个能直接跑起来的 Python + FastAPI 鉴权项目。


一、JWT 是什么?先记一句话

JWT 全称是 JSON Web Token

它是一种"紧凑、URL 安全"的令牌格式,用来在客户端和服务端之间传递认证信息。

典型 JWT 长这样(3 段):

xxxxx.yyyyy.zzzzz

三段分别是:

  • Header(头部)
  • Payload(载荷)
  • Signature(签名)

二、为什么会有 JWT?

传统 Session 方案中,服务端要保存会话状态;

而 JWT 走的是"无状态认证"思路:

  • 登录成功后,服务端签发 token 给客户端
  • 客户端后续每次请求带上 token
  • 服务端只要验签 + 校验声明,就能确认身份

好处:

  • 更适合前后端分离和分布式部署
  • 不依赖服务端 Session 共享
  • 跨服务传递身份信息更方便

三、JWT 出现前,token 一般怎么做?

很多同学会把"token"直接等同于 JWT。

其实在 JWT 普及前(包括现在),最常见的 token 方案有这几类:

  • Session ID(会话 ID)
  • Opaque Token(不透明令牌)
  • API Key(接口密钥)
  • SAML 票据/断言(企业场景较多)

先记一个核心区别:

  • JWT:token 里通常"自带信息"(可解码看到 claims)
  • 传统 token:token 本身通常是随机串,真正信息在服务端查

1)Session + Cookie(Web 时代主流)

怎么得到:

  1. 用户登录(用户名/密码)
  2. 服务端验证通过,创建 session 记录(用户 ID、过期时间等)
  3. 返回 session_id 给浏览器(一般放 Cookie)

怎么用:

  • 浏览器后续请求自动携带 Cookie
  • 服务端拿 session_id 去内存/Redis/DB 查会话
  • 查到放行,查不到就要求重新登录

优点:简单、可立即失效

缺点:服务端要存状态,分布式要做 session 共享

2)Opaque Token(OAuth2 早期常见)

很多授权服务器签发的 access token,本质是随机串而非 JWT。

怎么得到:

  • 走 OAuth2 流程(授权码、客户端凭证等)
  • 授权服务器签发随机 token

怎么用:

  • 客户端带 Authorization: Bearer <token>
  • 资源服务器去授权服务器做内省(introspection)或查本地缓存
  • 校验通过再放行

特点:集中控制、易撤销;但每次校验可能多一次网络开销

3)API Key(更早、更简单)

怎么得到:

  • 在平台后台创建应用,拿到 api_key(有时还配 api_secret

怎么用:

  • 一般放请求头(不推荐放 URL 查询参数)
  • 服务端校验 key 是否有效、权限范围、调用配额

适合服务到服务调用,但通常更偏"应用身份",不太适合用户登录态。

为什么后来 JWT 很火?

因为它特别适合前后端分离和微服务:

  • 服务端可无状态验证(不一定每次查库)
  • 跨服务传递用户身份方便
  • 标准化字段明确(claimsexpissaud

但代价是默认难"立即撤销",所以生产中常配套:

短时效 access token + refresh token + 黑名单机制。


四、JWT 三段式结构

1)Header

描述 token 元数据,比如签名算法:

json 复制代码
{
  "alg": "HS256",
  "typ": "JWT"
}

2)Payload

存放声明(Claims),比如用户 ID、过期时间:

json 复制代码
{
  "sub": "alice",
  "role": "admin",
  "exp": 1760000000
}

重点:Payload 是 Base64URL 编码,不是加密。

不要放密码、银行卡号等敏感数据。

3)Signature

签名用于防篡改,核心公式:

sign(base64url(header) + "." + base64url(payload), secret/private_key)

服务端收到 token 后会重新验签,一旦不一致就拒绝。


五、RFC 7519 里最常用的标准声明

JWT 标准(RFC 7519)里常见声明:

  • iss:签发者(issuer)
  • sub:主题(subject,一般放用户唯一标识)
  • aud:受众(audience)
  • exp:过期时间
  • nbf:生效时间(not before)
  • iat:签发时间(issued at)
  • jti:JWT 唯一 ID

初学者至少要把 sub + exp 用好,进阶再加 iss/aud/jti


六、JWT 的完整工作流(登录鉴权)

  1. 用户提交用户名密码到登录接口
  2. 服务端验证通过,签发 Access Token
  3. 客户端把 token 放在请求头:
    Authorization: Bearer <token>
  4. 服务端校验签名、过期时间、用户信息
  5. 校验通过,放行受保护接口;失败返回 401

七、JWT 安全使用的 8 条实践建议

  1. 全链路必须 HTTPS
  2. Access Token 有效期要短(如 15~30 分钟)
  3. 明确校验 exp,不要只验签名
  4. 不要在 Payload 放敏感信息
  5. 强制算法白名单(避免算法混淆)
  6. 密钥不要硬编码到仓库,使用环境变量
  7. 需要"退出立即失效"时,引入黑名单/版本号机制
  8. 高风险接口增加二次校验(短信、密码二验等)

八、HS256 vs RS256:初学者如何选

HS256(对称)

  • 签名和验签使用同一密钥
  • 部署简单,性能好
  • 适合单体或小规模服务

RS256(非对称)

  • 私钥签名,公钥验签
  • 服务间验证更安全,便于密钥管理
  • 适合微服务或多系统协作

初学者实战可以先用 HS256,理解流程后再升级 RS256。


九、实战项目:FastAPI JWT 鉴权 API

本文配套项目目录:fastapi_jwt_demo

技术栈:

  • Python 3.10+
  • FastAPI
  • Uvicorn
  • python-jose
  • passlib

项目实现:

  • 用户登录:POST /api/v1/auth/login
  • 获取当前用户:GET /api/v1/users/me(需要 token)
  • 待办列表:GET /api/v1/todos(需要 token)
  • 创建待办:POST /api/v1/todos(需要 token)

核心演示点:

  • 登录后签发 JWT(含 subexp
  • Bearer Token 鉴权
  • 过期 token 自动 401
  • 密码哈希存储(不是明文)

十、初学者最常见 6 个坑

坑 1:把敏感信息放进 Payload

错。JWT 默认可解码,Payload 不是保险箱。

坑 2:把超长有效期 access token 当常规方案

风险很高。泄露后攻击窗口太长。

坑 3:只校验签名,不校验 exp/nbf

会让过期 token 继续可用。

坑 4:密钥写死在代码里并上传仓库

这是安全事故高发点。

坑 5:把 JWT 当"可撤销 session"

JWT 天生无状态,不加额外机制就很难立即撤销。

坑 6:没区分"认证"和"授权"

JWT 证明"你是谁",权限控制还需要业务层规则。


十一、给初学者的学习路径

  1. 先实现登录 + /users/me
  2. 再给业务接口加鉴权依赖
  3. 增加 token 过期处理
  4. 再做 refresh token
  5. 最后引入数据库与权限模型(RBAC)

这样走,一周内你就能把 JWT 鉴权跑通并解释清楚。


十二、参考资料

相关推荐
笨鸟先飞,勤能补拙12 分钟前
AI 赋能网络安全:技术全景、成熟度评估与实战案例
人工智能·python·安全·web安全·网络安全·sqlite·github
长和信泰光伏储能1 小时前
京津冀光伏发电:绿色能源的未来之路
python·能源
浦信仿真大讲堂1 小时前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
Gu Gu Study2 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境3 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境3 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd1233 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
Dxy12393102163 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
bamb004 小时前
一个项目带你入门AI应用开发01
python
0566464 小时前
Python康复训练——常用标准库
开发语言·python·学习