2. JWT 工作原理:客户端与服务端交互流程、Token 的签发与验证过程、无状态认证的优势

2.1 核心交互流程:从登录到鉴权

JWT 分布式鉴权的核心在于客户端持有凭证,服务端不保存会话状态。一次完整的交互流程分为两个阶段:签发阶段和验证阶段。

核心原则:服务端只负责“验票”,不负责“记人”。每次请求都携带完整的身份信息,由服务端独立验证。

阶段一:Token 签发(登录)

  1. 客户端发起登录请求:用户通过浏览器或移动端提交用户名、密码到服务端认证接口(如 /api/login)。
  2. 服务端验证身份:服务端查询数据库,校验用户名密码是否正确。
  3. 服务端签发 JWT:验证通过后,服务端将用户标识(如 userId)、角色、过期时间等数据放入 JWT 载荷,使用密钥(Secret)或私钥(Private Key)进行签名,生成一个完整的 JWT 字符串。
  4. 返回 Token:服务端将 JWT 返回给客户端(通常在 HTTP Response Body 或 Header 中)。
  5. 客户端存储 Token:客户端将 JWT 存储在本地(如浏览器的 localStorage、sessionStorage 或移动端的本地存储)。

阶段二:Token 验证(请求)

  1. 客户端发起业务请求:客户端在请求头(通常是 Authorization: Bearer <token>)中携带 JWT。
  2. 服务端拦截并解析:服务端通过过滤器或拦截器获取请求头中的 JWT。
  3. 服务端验证签名:服务端使用相同的密钥或公钥验证 JWT 的签名是否有效,同时检查 exp(过期时间)等声明。
  4. 提取用户信息:验证通过后,服务端从 JWT 载荷中解析出用户身份和权限信息。
  5. 执行权限判断:服务端根据解析出的信息判断用户是否有权访问该资源。
  6. 返回业务数据:权限验证通过,服务端处理请求并返回结果。
JWT 客户端与服务端交互流程 客户端 服务端 1. 登录请求 2. 验证身份 3. 签发 JWT 4. 返回 Token 5. 存储 Token 6. 携带 Token 请求 7. 验证 Token 8. 返回业务数据 服务端不保存 Token, 每次请求独立验证签名。

2.2 Token 的签发与验证过程详解

JWT 的签发与验证是非对称或对称加密算法的典型应用。下面以最常用的 HS256(对称)和 RS256(非对称)为例,拆解其内部机制。

2.2.1 签发过程(Signing)

服务端将用户信息打包成 JWT 的三个部分,并生成签名。

步骤 操作 说明
1 构建 Header 指定算法(如 HS256)和 Token 类型(JWT)。
2 构建 Payload 放入标准声明(iss、exp、sub)和自定义声明(如 userId、role)。
3 编码 Header 和 Payload 使用 Base64URL 编码,生成两个字符串。
4 生成签名 将编码后的 Header 和 Payload 用 . 连接,使用密钥进行 HMAC-SHA256 或 RSA-SHA256 计算,得到签名。
5 组合 JWT 将 Header.Payload.Signature 用 . 连接,形成最终 Token。
关键点:签名是使用密钥对前两部分内容的哈希值进行加密的结果。任何对 Header 或 Payload 的篡改,都会导致签名验证失败。

2.2.2 验证过程(Verification)

服务端收到 JWT 后,执行逆向操作以确认 Token 的真实性和完整性。

  1. 拆分 Token:按 . 将 JWT 拆分为 Header、Payload、Signature 三部分。
  2. 解码 Header:Base64URL 解码 Header,获取算法信息。
  3. 重新计算签名:使用相同的算法和密钥,对接收到的 Header 和 Payload 重新计算签名。
  4. 比对签名:将计算出的签名与 Token 中的签名进行比对。如果一致,则通过;否则拒绝。
  5. 校验声明:检查 exp(是否过期)、nbf(是否生效)、iss(是否可信)等。
  6. 提取数据:验证通过后,解码 Payload 获取用户信息。
JWT 签发与验证过程(HS256) 签发阶段 验证阶段 Header + Payload Base64URL 编码 密钥 (Secret) HMAC-SHA256 生成签名 组合 JWT 拆分 JWT 解码 Header 密钥 (Secret) 重新计算签名 比对签名 提取 Payload 相同密钥 对称加密

2.3 无状态认证的优势

JWT 最核心的价值在于无状态(Stateless)。与传统的基于 Session 的有状态认证相比,它在分布式架构下具有显著优势。

对比维度 传统 Session 认证(有状态) JWT 认证(无状态)
存储位置 Session 数据存储在服务端内存或 Redis 中。 Token 数据存储在客户端,服务端不保存。
扩展性 需要 Session 共享(如 Redis 集中存储),否则多节点无法同步。 天然支持水平扩展,任何节点均可独立验证 Token。
性能 每次请求需查询 Session 存储,存在 I/O 开销。 仅需本地计算签名,无 I/O 开销,性能更高。
跨域/跨系统 Session 难以跨域共享,需额外配置。 Token 可轻松在多个微服务、移动端、第三方应用间传递。
安全性 Session ID 泄露后,攻击者需获取服务端 Session 数据。 Token 泄露后,攻击者直接获得用户身份,需配合 HTTPS 和短有效期。
服务端压力 大量用户在线时,Session 存储占用大量服务端资源。 服务端无需存储,资源消耗极低。
注意:无状态也意味着无法主动吊销 Token。如果用户密码泄露或需要强制下线,必须等待 Token 过期或依赖黑名单机制(黑名单会引入状态,需权衡使用)。

2.3.1 分布式场景下的核心优势

  • 零共享:微服务 A 和微服务 B 不需要共享 Session 存储,各自使用相同的密钥即可验证 Token。
  • 低延迟:验证过程是纯 CPU 计算,不依赖网络 I/O(如查询 Redis),适合高并发场景。
  • 解耦:认证服务只负责签发 Token,业务服务只负责验证 Token,职责清晰。

2.3.2 适用场景与避坑

场景 推荐度 说明
单点登录(SSO) ⭐⭐⭐⭐⭐ JWT 天然适合跨系统身份传递。
移动端 API ⭐⭐⭐⭐⭐ 无 Cookie 依赖,适配原生存储。
微服务网关 ⭐⭐⭐⭐⭐ 网关统一验证 Token,下游服务无需重复鉴权。
需要强制吊销的场景 ⭐⭐⭐ 需配合黑名单或短有效期,增加复杂度。
最佳实践:在分布式系统中,建议使用 RS256(非对称)。认证服务持有私钥签发 Token,所有业务服务只持有公钥验证 Token。私钥不泄露,公钥可安全分发,安全性更高。