一、概念与本质
-
Token(令牌)
- 广义上是"用于身份验证的字符串",是一种抽象概念,没有固定格式,可由开发者自定义结构(如随机字符串、包含简单信息的字符串等)。
- 作用:替代传统的"账号密码"登录方式,用户登录后服务器生成 Token 并返回,后续请求携带 Token 即可证明身份(避免重复登录)。
-
JWT(JSON Web Token)
- 是 Token 的一种标准化实现,遵循 RFC 7519 规范,有固定的 JSON 结构和签名机制。
- 格式:由 Header(头部)、Payload(载荷)、Signature(签名) 三部分组成,用
.
拼接(如eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkiLCJuYW1lIjoiSm9obiBEb2UifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
)。
二、核心区别(表格对比)
维度 | Token(普通令牌) | JWT |
---|---|---|
结构 | 无固定格式,可自定义(如随机字符串 x8f2j1k9 ) |
固定三部分结构(Header + Payload + Signature) |
信息存储 | 通常不包含用户信息,需服务器查询数据库验证 | 载荷(Payload)中可包含用户基本信息(如 ID、角色),无需查库验证 |
验证方式 | 服务器需查询数据库/缓存(如 Redis)确认有效性 | 通过签名验证(无需查库),直接判断是否被篡改 |
状态性 | 通常是"有状态"的(服务器需存储 Token 状态) | 是"无状态"的(服务器无需存储,仅通过签名验证) |
安全性 | 依赖服务器存储的有效性(如注销需删除 Token) | 依赖签名密钥(密钥泄露则 Token 可伪造) |
三、使用场景对比
-
普通 Token 适用场景
- 需要灵活控制 Token 生命周期 (如随时注销、修改权限):
例:用户登录后,服务器生成随机 Token 并存入 Redis,设置过期时间。用户注销时,直接从 Redis 中删除 Token 即可失效。 - 对 Token 结构无标准化要求,需自定义扩展信息。
- 需要灵活控制 Token 生命周期 (如随时注销、修改权限):
-
JWT 适用场景
- 分布式系统 (多服务间共享身份验证):
例:用户在 A 服务登录后,生成 JWT 令牌,访问 B 服务时无需再次登录,B 服务直接通过签名验证 JWT 有效性(无需访问 A 服务的数据库)。 - 无需频繁查询数据库的轻量验证(如 API 接口授权):
JWT 载荷中可包含用户 ID、角色等信息,验证时直接解析使用,减少数据库压力。
- 分布式系统 (多服务间共享身份验证):
四、问题
1. 问:JWT 为什么是无状态的?
- 答:JWT 的验证不依赖服务器存储的状态,仅通过签名算法(如 HMAC SHA256)验证 Token 是否被篡改。服务器无需存储 JWT 内容,只需保存签名密钥,因此是无状态的,适合分布式系统。
2. 问:JWT 如何注销?
- 答 :JWT 本身无法直接注销(因无状态),常见解决方案:
- 维护一个"黑名单"(如 Redis 存储已注销的 JWT ID),验证时先检查是否在黑名单中;
- 缩短 JWT 有效期(如 15 分钟),配合刷新令牌(Refresh Token)机制。
3. 问:什么时候用普通 Token 而不用 JWT?
- 答 :当需要实时控制 Token 有效性(如用户修改密码后立即让旧 Token 失效)时,普通 Token 更合适。因为 JWT 一旦生成无法撤回,必须等过期才失效,而普通 Token 可通过删除服务器存储直接注销。
五、总结话术
"JWT 是 Token 的一种具体实现,核心区别在于:
- 普通 Token 是'有状态'的,依赖服务器存储验证,适合需要灵活控制生命周期的场景;
- JWT 是'无状态'的,自带用户信息和签名,适合分布式系统和轻量验证。
实际项目中,我们会根据场景选择:用户系统需要实时注销功能时用普通 Token + Redis;而跨服务 API 授权则用 JWT 减少数据库交互,提升性能。"