JavaScript 面试题
目录

请解释 JWT (JSON Web Token) 的概念、结构和应用场景。

· 约 6 分钟读完 · 第 252 / 507 章

推荐答案

JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用环境间安全地传输声明。它使用 JSON 对象作为载体,通过数字签名的方式来保证数据的完整性和真实性。JWT 本身是无状态的,意味着服务端不需要存储会话信息,这有助于提高系统的可伸缩性。

JWT 的结构:

一个 JWT 通常包含三个部分,它们通过 . 分隔:

  1. Header(头部):

    • 定义了令牌的元数据,通常包含令牌的类型(typ,通常为 "JWT")和所使用的签名算法(alg,例如 "HS256" 或 "RS256")。
    • 示例:{"alg": "HS256", "typ": "JWT"}
    • 会被 Base64Url 编码。
  2. Payload(载荷):

    • 包含了实际要传输的声明(claims)。
    • 这些声明可以是预定义的(registered claims,如 iss、sub、aud、exp、nbf、iat、jti),也可以是自定义的(private claims)。
    • 示例:{"sub": "1234567890", "name": "John Doe", "admin": true, "iat": 1516239022}
    • 会被 Base64Url 编码。
  3. Signature(签名):

    • 用于验证令牌的完整性和真实性。
    • 签名是通过使用 Header 中指定的算法,结合 Header 和 Payload 的 Base64Url 编码后的字符串以及一个密钥(secret key)计算出来的。
    • 示例(使用 HS256 算法):HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
    • 会被 Base64Url 编码。

JWT 的应用场景:

  • 身份验证 (Authentication):
    • 最常见的用途。当用户成功登录后,服务端会生成一个 JWT 并返回给客户端。客户端在后续的请求中,将 JWT 放在请求头中发送,服务端通过验证 JWT 来确认用户的身份。
  • 信息交换 (Information Exchange):
    • 由于 JWT 可以被签名,发送者可以确认信息的发送者身份,同时接收者也可以验证信息是否在传输过程中被篡改。
    • 可以安全地传输用户相关的声明信息。
  • 授权 (Authorization):
    • 服务端可以基于JWT中的权限信息来控制用户对资源的访问。

本题详细解读

概念详解:

JWT 的核心思想是使用一个加密的字符串(令牌)来表示一组声明(claims)。这些声明可以包含任何需要的信息,例如用户身份、权限、有效时间等。JWT 是一种基于 Token 的认证方式,它不像传统的基于 Session 的认证那样需要在服务端存储会话信息,因此更易于扩展和部署。

结构详细说明:

  1. Header:

    • typ: 指示令牌类型,固定为 JWT。
    • alg: 指示签名算法。常见的有以下几种:
      • HS256:使用 HMAC SHA256 算法进行签名,需要一个共享密钥(secret key)。
      • RS256:使用 RSA SHA256 算法进行签名,需要一个私钥和一个公钥。私钥用于签名,公钥用于验证。
      • ES256:使用 ECDSA SHA256 算法进行签名,与 RS256 类似,但基于椭圆曲线加密。
  2. Payload:

    • Registered Claims:
      • iss (Issuer):令牌的颁发者。
      • sub (Subject):令牌的主题,通常是用户 ID。
      • aud (Audience):令牌的接收者。
      • exp (Expiration Time):令牌的过期时间,时间戳形式。
      • nbf (Not Before):令牌生效时间,时间戳形式。
      • iat (Issued At):令牌颁发时间,时间戳形式。
      • jti (JWT ID):令牌的唯一标识符,可以用于防止令牌重复使用。
    • Private Claims:
      • 自定义的声明,用于存储特定于应用的信息,例如用户角色,权限等。
  3. Signature:

    • 签名的计算方法是:将 Base64Url 编码的 Header 和 Payload 连接起来(中间用 . 分隔),然后使用 Header 中指定的签名算法和密钥(secret key 或者私钥)对这个连接后的字符串进行签名。
    • 验证签名时,需要使用相应的密钥(secret key 或者公钥)和签名算法对 Header 和 Payload 进行重新签名,如果计算出的签名与 JWT 中的签名一致,则表明令牌是有效的,并且没有被篡改。

应用场景细化:

  • 身份验证:

    • 用户登录成功后,服务端生成包含用户身份信息的 JWT,并返回给客户端。
    • 客户端存储 JWT(通常在 HTTP Only 的 cookie 或 localStorage 中)。
    • 客户端在后续请求中,将 JWT 放置在 HTTP 请求头的 Authorization 字段中,通常采用 Bearer 模式 (例如:Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c )
    • 服务端收到请求后,验证 JWT 的签名和过期时间,确认用户身份。
  • 信息交换:

    • 在微服务架构中,可以使用 JWT 来传输服务之间交互的信息。
    • 例如,一个服务可以使用 JWT 来传递用户上下文信息给另一个服务,减少数据库查询。
  • 授权:

    • JWT 的 payload 中可以包含用户的角色和权限信息。
    • 服务端在验证 JWT 的同时,可以提取 payload 中的权限信息,用于控制用户对资源的访问权限。
    • 例如:如果payload中包含"admin": true,服务端可以允许该用户访问管理页面。

总结: (不应该有)