Skip to content

说说 jwt 中的 token,是怎么进行身份验证的?

参考答案:

JWT(JSON Web Token)是一种用于 身份验证授权 的开源标准。它是一种将用户身份信息 编码为一个 Token 的形式进行身份验证的机制。JWT 是基于 JSON 格式的令牌,并且是自包含的,即它包含了验证用户身份和权限所需的所有信息。通过 JWT,前后端可以进行无状态的认证。

1. JWT 的结构

JWT 的结构是由三个部分组成的,使用点 . 分隔:

Header.Payload.Signature

这三个部分分别是:

  • Header(头部):包含算法和令牌类型的元数据。
  • Payload(负载):包含用户的身份信息(比如用户 ID、角色)以及其他自定义数据。
  • Signature(签名):用于确保 Token 在传输过程中没有被篡改。

示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
  • Header 部分内容:
    json
    {
      "alg": "HS256",  // 签名算法 HMAC-SHA256
      "typ": "JWT"     // Token 类型为 JWT
    }
  • Payload 部分内容:
    json
    {
      "sub": "1234567890", // 用户 ID
      "name": "John Doe",  // 用户名称
      "iat": 1516239022    // Token 的签发时间
    }
  • Signature 是用指定的算法和密钥加密生成的:
    HMACSHA256(
      base64UrlEncode(header) + "." + base64UrlEncode(payload),
      secret
    )

2. JWT 身份验证的流程

身份验证流程通过以下几个步骤来完成:

1. 用户登录

用户通过登录页面提交用户名和密码,后端服务器验证用户的身份信息。

2. 生成 JWT Token

一旦用户通过身份验证,服务器会生成一个 JWT Token。生成的 Token 包含了用户身份相关的信息(例如用户 ID 或角色),这些信息被编码在 Payload 中。然后服务器使用 私钥(或预定义的密钥)对 Token 进行签名。

3. 前端存储 Token

服务器将生成的 JWT 返回给前端。前端通常会将 JWT 存储在 LocalStorageSessionStorage 中,或者作为 Cookie 存储在客户端。

4. 携带 Token 发起请求

在用户登录后,前端每次请求需要认证的资源时,将 JWT 放入 HTTP 请求头的 Authorization 字段 中(通常是 Bearer Token 形式),例如:

http
Authorization: Bearer <JWT_Token>

5. 后端验证 JWT

服务器接收到前端携带的 JWT 后,会对其进行验证:

  • 验证签名:服务器使用预先定义的密钥(私钥)对 JWT 的签名部分进行解密,验证它没有被篡改。
  • 验证有效性:服务器检查 Token 是否过期(通过 exp 字段)或是否具备访问资源的权限(通过角色或权限字段)。

如果 Token 验证通过,服务器就会返回用户请求的数据,否则返回 401 Unauthorized403 Forbidden 的错误。

6. 续签或刷新 Token

如果 Token 过期,通常会提供 刷新 Token 的机制,允许用户使用一个短时效的 Refresh Token 来获取新的 JWT。

3. JWT 的优势

  • 无状态认证:JWT 是无状态的,不需要在服务器端存储 Token,因此服务器可以扩展得更好。服务器不需要保存用户的会话状态,所有信息都在 Token 中自包含。
  • 跨域认证:JWT 可以在多个不同的域中使用,因此特别适合在微服务架构中使用。
  • 减少数据库查询:由于 JWT 包含了用户的信息,服务器在每次请求时不需要查询数据库来获取用户信息。

4. JWT 的安全性考量

虽然 JWT 自带签名以防篡改,但它并不自带加密,所有的信息都是 明文 存在于 Token 的 Payload 中。因此,以下是一些安全性考量:

  • 不要在 Payload 中存放敏感数据:由于 JWT 的 Payload 是可解码的,不能将敏感信息(如密码)直接存入 Payload。
  • Token 过期机制:JWT 应该设置 过期时间 (exp),确保 Token 不会被长期使用。一旦 Token 过期,用户需要重新登录或使用刷新 Token 获取新 Token。
  • HTTPS 传输:在传输 Token 时,应该使用 HTTPS 确保通信的安全,防止 Token 被窃取。
  • 刷新 Token 机制:可以设计一个更短时效的 Refresh Token,用户可以使用它在 Token 过期后获取新的 Token。

5. JWT 的局限性

  • Token 无法撤销:JWT 是无状态的,因此在 Token 发出后,服务器无法主动撤销它。如果用户登出或者 Token 泄漏,服务器无法使其失效,除非等待 Token 过期。
  • Token 体积较大:由于 JWT 是自包含的,它可能比传统的会话 Token 体积要大,传输频繁时可能会影响性能。

总结

JWT 是一种轻量级的身份验证机制,适用于无状态的应用场景,尤其在微服务架构和跨域场景下十分有用。通过对 JWT 的签名机制,可以保证 Token 的完整性和可靠性,但需要注意不能将敏感数据放在 JWT 中,并确保 Token 的安全传输和使用。