2. Token 基础概念:什么是 Token、Token 与 Session 的区别、JWT 结构解析
在分布式系统与微服务架构中,Token 已成为身份认证与授权的事实标准。理解 Token 的本质、它与传统 Session 的差异,以及最广泛使用的 JWT(JSON Web Token)结构,是构建安全缓存拦截链路的前提。
2.1 什么是 Token
Token(令牌)是一段经过签名的、包含用户身份与权限信息的字符串。它由服务端签发,客户端在后续请求中携带,服务端通过验证 Token 的签名与有效期来确认请求者的身份。
核心特征:Token 是 无状态 的认证凭证。服务端不需要存储会话信息,所有必要数据都编码在 Token 本身。
Token 的典型工作流程如下:
- 登录请求:客户端提交用户名/密码到认证服务。
- 签发 Token:认证服务验证凭据后,生成一个包含用户 ID、角色、过期时间等信息的 Token,并返回给客户端。
- 携带 Token:客户端将 Token 存储在本地(如 localStorage、Cookie),并在每次 API 请求的 HTTP Header 中携带(通常为
Authorization: Bearer <token>)。 - 验证 Token:后端服务(或 API 网关)拦截请求,验证 Token 的签名与有效性,从中提取用户信息,决定是否放行。
Token 的三大优势:
- 无状态扩展:服务端无需维护会话存储,水平扩展时无需同步 Session。
- 跨域/跨服务:Token 可以在不同域名、不同服务间传递,适合微服务与单点登录(SSO)。
- 自包含:用户信息直接编码在 Token 中,减少数据库查询。
2.2 Token 与 Session 的区别
Session 是传统的服务端会话管理方式,Token 是更现代的无状态认证方案。两者在存储位置、扩展性、安全性等方面存在显著差异。
| 对比维度 | Session | Token |
|---|---|---|
| 存储位置 | 服务端内存/Redis/数据库 | 客户端(Token 字符串) |
| 状态特性 | 有状态,服务端维护会话 | 无状态,服务端不存储 |
| 扩展性 | 需要共享 Session 存储(如 Redis) | 天然支持水平扩展 |
| 跨域支持 | 困难,受 Cookie 同源策略限制 | 良好,通过 HTTP Header 传递 |
| 性能开销 | 每次请求需查询 Session 存储 | 仅需验证签名,无需存储查询 |
| 安全性 | 依赖 Cookie 的 HttpOnly/Secure 属性 | 依赖签名算法与密钥管理 |
| 吊销机制 | 直接删除 Session 即可 | 需要黑名单或短有效期 |
架构选择建议:
- 单体应用或小型项目:Session 方案简单直接。
- 微服务、前后端分离、移动端:Token 方案更灵活。
- 高安全场景:Token 需配合短有效期 + 刷新令牌(Refresh Token)使用。
2.3 JWT 结构解析
JWT(JSON Web Token)是目前最流行的 Token 实现标准(RFC 7519)。它由三部分组成,使用 Base64URL 编码,以点号(.)分隔。
// JWT 示例
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
JWT 的三部分结构如下:
| 部分 | 名称 | 内容 | 示例(解码后) |
|---|---|---|---|
| Header | 头部 | 签名算法(alg)和令牌类型(typ) | {"alg":"HS256","typ":"JWT"} |
| Payload | 载荷 | 声明(Claims):用户数据、过期时间等 | {"sub":"1234567890","name":"John Doe","iat":1516239022} |
| Signature | 签名 | 对 Header 和 Payload 的签名,防止篡改 | HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) |
Payload 中的标准声明(Registered Claims):
iss(Issuer):签发者sub(Subject):主题(通常为用户 ID)aud(Audience):接收方exp(Expiration Time):过期时间(UNIX 时间戳)nbf(Not Before):生效时间iat(Issued At):签发时间
2.4 JWT 签名算法与安全要点
JWT 的安全性高度依赖签名算法和密钥管理。常见的签名算法分为两类:
| 算法类型 | 算法 | 特点 | 适用场景 |
|---|---|---|---|
| 对称签名 | HS256 / HS384 / HS512 | 使用同一个密钥签名和验证,速度快 | 单一服务内部,密钥不对外暴露 |
| 非对称签名 | RS256 / ES256 / ES384 | 私钥签名,公钥验证,密钥分离 | 微服务间认证、第三方集成 |
JWT 安全红线:
- 不要将密码等敏感信息放入 Payload:Payload 仅 Base64 编码,可被解码读取。
- 必须验证签名:防止攻击者伪造或篡改 Token。
- 设置合理的过期时间(exp):建议 15 分钟~2 小时,配合 Refresh Token 使用。
- 防范算法混淆攻击:服务端应明确指定允许的算法,拒绝
alg: "none"。 - 密钥定期轮换:对称密钥或非对称私钥应定期更新。
2.5 Token 在 Redis 缓存后端中的角色
在 Redis 缓存后端架构中,Token 主要承担以下角色:
- 认证凭证:客户端携带 JWT 访问 API,网关或业务服务验证 JWT 签名后放行。
- 缓存键的一部分:JWT 中的
sub(用户 ID)或jti(JWT ID)可作为 Redis 缓存键的组成部分,实现用户级缓存隔离。 - 黑名单存储:当需要提前吊销 JWT 时,将
jti存入 Redis 黑名单,设置与 JWT 相同的过期时间。 - 刷新令牌管理:Refresh Token 存储在 Redis 中,支持过期自动清理,实现安全的 Token 续期。