JWT-token basics

JWT(JSON Web Token) 是一种开放标准(RFC 7519),用于在网络应用环境间传递声明信息的安全方式。它由三部分组成:头部(Header)有效载荷(Payload)签名(Signature),通过使用基于 JSON 的格式来表示。

JWT 常用于身份验证和信息交换,在现代 Web 应用中,特别是在 API 和单点登录(SSO)中应用广泛。


JWT 的结构

JWT 是由三部分组成的字符串,中间用 . 分隔,格式如下:

1
<Header>.<Payload>.<Signature>

1. Header(头部)

Header 通常由两部分信息组成:令牌的类型(通常是 JWT)和所使用的签名算法(如 HS256RS256)。

示例

1
2
3
4
{
"alg": "HS256",
"typ": "JWT"
}
  • alg:签名算法,表示如何加密 JWT,例如 HMAC SHA256 (HS256) 或 RSA SHA256 (RS256)。
  • typ:表示 JWT 类型,通常是 “JWT”。

这部分被 Base64Url 编码,形成 JWT 的第一部分。

2. Payload(有效载荷)

Payload 部分包含了传递的数据,也叫做“声明(claims)”。声明分为三种类型:

  • 注册声明(Registered claims):这些是 JWT 中的预定义字段,用于提供一些公共的、有用的信息。
    • iss(Issuer):签发人
    • sub(Subject):主题
    • aud(Audience):接收方
    • exp(Expiration Time):过期时间,UNIX 时间戳格式
    • nbf(Not Before):在此时间之前不可用
    • iat(Issued At):签发时间
    • jti(JWT ID):JWT 的唯一标识符
  • 公共声明(Public claims):可以自定义的信息,需要确保不会与其他方的声明冲突。
  • 私有声明(Private claims):双方自定义的声明,通常是用于在特定的应用中传递信息(如用户 ID、角色等)。

示例

1
2
3
4
5
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}

这部分数据也会被 Base64Url 编码,形成 JWT 的第二部分。

3. Signature(签名)

签名是用来验证消息的真实性和完整性,确保数据在传输过程中没有被篡改。签名是通过将前两部分(Header 和 Payload)与一个密钥结合,并使用指定的签名算法进行加密生成的。

生成签名的步骤

  1. 对 Header 和 Payload 使用 Base64Url 编码。
  2. 将编码后的 Header 和 Payload 用 . 连接。
  3. 使用密钥和指定的算法(如 HS256)对连接后的字符串进行签名。

示例

1
2
3
4
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)

签名部分用于验证 JWT 是否未被篡改,并且可以验证发送者的身份。如果签名不匹配,说明数据被篡改或密钥不正确。


JWT 工作原理

  1. 用户登录
    • 用户向服务器提交用户名和密码。
    • 服务器验证用户身份后,生成一个 JWT 并将其返回给客户端。这个 JWT 中通常包含用户的 ID、角色信息以及过期时间等。
  2. 客户端存储
    • 客户端(如浏览器、移动设备等)将 JWT 存储在本地(通常是 localStoragesessionStorage)或 HTTP cookie 中。
  3. 客户端请求 API
    • 在每次请求时,客户端将 JWT 添加到请求头中,通常通过 Authorization 字段传递。
      1
      Authorization: Bearer <JWT>
  4. 服务器验证
    • 服务器接收到请求后,从请求头中提取 JWT。
    • 服务器使用预先存储的密钥(对于对称加密算法)或公钥(对于非对称加密算法)验证签名是否有效。如果有效,服务器将解码 JWT,获取其中的有效载荷,并根据这些信息处理请求(如获取用户信息、授权等)。
  5. 返回响应
    • 如果 JWT 验证通过,服务器返回请求的资源。如果验证失败,服务器返回 401 Unauthorized 错误。

JWT 的优点

  1. 无状态认证(Stateless Authentication)

    • 由于所有的信息都保存在 JWT 本身,服务器不需要存储会话信息,因此可以实现无状态认证。每个请求都可以通过 JWT 独立验证,简化了后端的状态管理。
  2. 跨平台支持

    • JWT 使用 JSON 格式,可以在不同的平台和编程语言中方便地解析和生成。
  3. 分布式系统友好

    • JWT 适用于分布式系统中,因为它不依赖于中央存储。每个微服务可以独立验证 JWT,而无需访问集中式数据库或会话存储。
  4. 灵活性和扩展性

    • JWT 支持自定义声明,可以根据需求存储额外的用户信息和应用上下文。

JWT 的缺点

  1. 无法撤销

    • 一旦生成 JWT,它将一直有效,直到过期。如果 JWT 被盗,攻击者可以在有效期内访问受保护的资源。没有内建的机制来撤销 JWT,因此需要其他机制(如黑名单)来处理这种情况。
  2. JWT 较大

    • 由于 JWT 中包含了用户信息,可能会导致其相对较大,尤其是在需要存储较多信息时。每个请求都要携带这个 token,可能会增加网络传输的开销。
  3. 密钥管理问题

    • 如果使用对称加密算法(如 HS256),密钥的泄露可能导致所有 JWT 的安全性受到威胁。如果使用非对称加密算法(如 RS256),密钥对的管理可能会更复杂。

JWT 使用场景

  1. 身份认证

    • 在用户登录时,服务器生成一个 JWT,并将其返回给客户端。之后,客户端每次向服务器发起请求时,都会携带 JWT,以进行身份验证。
  2. 信息交换

    • JWT 可以用来安全地在各方之间交换信息,JWT 的签名可以保证数据在传输过程中未被篡改。
  3. 单点登录(SSO)

    • 多个应用可以共享一个统一的 JWT 进行身份验证,实现跨域和跨平台的单点登录。

总结

JWT 是一种轻量级的、可扩展的方式,用于在分布式系统中传递身份验证信息和其他数据。它的优点在于能够实现无状态的认证,并且可以灵活地扩展和自定义。然而,它也有一些缺点,例如没有内置的撤销机制和较大的尺寸,使用时需要考虑这些问题。