Python 认证与 JWT
Python Web 服务中使用 JWT 作为短期 Access Token 时的实现边界,以及它与 Session、Refresh 和资源级 Authorization 的关系。
[!info] related notes
- 所属 MOC:Web 后端 · 学习路线
- 通用认证模型:Stateful、Stateless 与 Hybrid 认证架构
- 凭证概念:Access Token · Refresh Token · JWT · Server-side Session 鉴权
- 相关:FastAPI · 配置
Python 认证与 JWT
一句话定义
在 FastAPI、Django 等 Python Web 服务中,JWT 常作为短生命周期 Access Token;但 JWT 只是凭证格式,是否使用 Server-side Session、Refresh Token、Redis/数据库状态是独立的架构决策。
一个清晰模型
Access JWT
→ 普通 API 的短期身份凭证
Refresh Token
→ 续期凭证,可绑定服务端 Session / Grant
Session / Grant
→ 长期登录生命周期与撤销状态
Authorization
→ 当前身份能否操作当前资源
不要把这四层揉成“JWT 认证”。
Pure Session 与 Hybrid
Pure Server-side Session
HttpOnly Cookie
→ opaque Session Token
→ Session Store lookup
Browser App 完全可以使用这种方案,不需要 JWT。
Hybrid
normal request
→ short-lived Access JWT local verify
refresh / logout / revoke
→ Refresh Token
→ server-side Session / Grant
这种模式适合希望普通 API 不每次访问 Session Store,但仍然保留长期撤销和设备生命周期控制的系统。
JWT Claims
常见 claims:
sub
exp
iat
iss
aud
scope / roles(按需)
生产代码应使用成熟 JWT 库进行签名与验证,而不是自己拼接 Base64。
JWT Payload 默认可读,所以不放密码、密钥和不必要的敏感信息。
验证边界
认证依赖不能只做 decode,至少按场景考虑:
- signature;
- allowed algorithm;
exp/nbf;iss/aud;- 必要 claims 的类型与语义。
验证成功后得到的是 principal / claims,不是所有业务操作的最终权限结论。
Authorization
例如 Token 中:
sub = user-42
scope = assessment:write
仍然需要在 Service/Policy/Repository 中判断:
Assessment 789 是否属于 user-42?
当前组织成员资格是否仍有效?
资源当前状态是否允许修改?
FastAPI dependency 或 Django middleware 可以建立请求级身份,但资源级 Authorization 仍应显式实现。
Refresh 与撤销
Refresh Token 可以是 opaque random string,不需要 JWT。
安全的长期生命周期通常还要考虑:
- server-side revoke state;
- expiry;
- rotation;
- replay/reuse detection;
- device/session binding。
如果 Access JWT 走纯本地验证,那么服务端 Session 被撤销后,这个已签发 Access Token 可能继续工作到 exp;短 TTL 只是限制这个滞后窗口。
常见误区
- “JWT = 无状态认证架构” → JWT 只是格式。
- “JWT 自动更安全” → 安全取决于密钥、claims 验证、传输和生命周期设计。
- “Refresh Token 必须 JWT” → 不需要。
- “Bearer Token 验证成功就完成业务授权” → 仍需资源级 Policy。
- “localStorage 是 JWT 标准存储” → 不存在这种统一标准,Browser 要结合 XSS/CSRF 威胁模型选择。
最短记忆
Python Web 中 JWT 最适合被理解为一种 Access Token 格式;Session、Refresh 和 Authorization 是独立但协作的层。