使用 JSON Web Token (JWT) 实现单点登录 (SSO) 是一种常见的方式,因为 JWT 可以在多个服务之间安全地传递用户的身份信息。以下是 JWT 实现单点登录的一般流程:

1. 用户登录

  • 用户访问登录页面并输入凭据(如用户名和密码)。
  • 认证服务验证用户的凭据。如果验证成功,则生成一个 JWT。这个 JWT 包含了用户的身份信息和权限,通常还会包含一个过期时间(exp 声明)。

2. 生成 JWT

  • 认证服务将用户信息(如用户 ID、角色、权限等)编码成 JWT。JWT 通常由三部分组成:
    1. Header: 描述了签名算法和类型(如 HS256)。
    2. Payload: 包含用户的身份信息和其他声明(如用户 ID、权限、过期时间等)。
    3. Signature: 使用密钥对前两部分(Header 和 Payload)进行签名,以确保 JWT 的完整性和安全性。
  • 生成后的 JWT 通过 HTTP 响应返回给客户端。

3. 客户端存储 JWT

  • 客户端通常会将 JWT 存储在浏览器的 localStoragesessionStorage 中,或者存储在一个安全的 Cookie 中(通常设置为 HttpOnly 和 Secure)。

4. 访问受保护的资源

  • 在用户访问其他服务或资源时,客户端会在请求的 Authorization 头中携带 JWT(如 Authorization: Bearer <JWT>)。
  • 每个微服务或应用都会验证该 JWT 的有效性,以确定用户的身份和权限。

5. 验证 JWT

  • 接收到请求的服务会使用预共享的密钥来验证 JWT 的签名,以确保 JWT 未被篡改。
  • 服务还会检查 JWT 的过期时间(exp 声明)以确定 JWT 是否已经过期。
  • 如果 JWT 验证通过,服务将允许访问受保护的资源。

6. 单点登录的特点

  • 单一登录点:用户在一个地方(认证服务)登录后,其他服务可以使用 JWT 进行身份验证,无需再次登录。
  • 跨服务共享:JWT 可以在多个服务之间安全传递,确保不同的服务都可以验证用户身份而无需与中心认证服务直接交互。
  • 无状态:JWT 本质上是无状态的,不需要服务器端存储任何会话信息,这使得它非常适合分布式系统和微服务架构。

7. JWT 刷新机制

  • 为了安全性,JWT 通常有一个较短的过期时间。当 JWT 过期时,用户需要刷新 JWT。常见的做法是使用一个长时间有效的刷新令牌来请求新的 JWT,而无需重新登录。
  • 刷新令牌通常比访问令牌(JWT)更长久,且安全性更高,因为刷新令牌只在认证服务器上存储和使用,不会暴露给其他服务。

8. 登出机制

  • 因为 JWT 是无状态的,服务器无法主动废止一个已经签发的 JWT。常见的登出机制包括:
    • 短过期时间:减少 JWT 的有效期,迫使用户频繁地获取新的令牌。
    • 黑名单:在服务端维护一个黑名单列表,将已经登出的 JWT 添加进去,在验证 JWT 时检查是否在黑名单中。

图解 JWT SSO 流程

[Client] -> Login -> [Auth Server] -> Generate JWT -> [Client]
[Client] -> Access Resource -> [Service 1] -> Verify JWT -> [Client]
[Client] -> Access Resource -> [Service 2] -> Verify JWT -> [Client]

结论

JWT 实现的单点登录机制通过使用令牌来确保用户在多个系统中保持登录状态,同时保持了系统的无状态性和扩展性。它在现代分布式系统和微服务架构中非常受欢迎。