JSON Web Token


一、定义

JWT(JSON Web Token)是一种开放标准(RFC 7519),它定义了一种紧凑和独立的方式,用于在各方之间以JSON对象安全地传递信息。这个信息可以被验证和信任,因为它是数字签名的。JWT通常用于身份验证和信息交换。

二、结构

2.1 Header(头部)

  • 通常包含两部分:令牌的类型(即JWT)和所使用的签名算法,如HMAC SHA256或RSA。

例如,一个典型的Header可能如下:

{
  "alg": "HS256",
  "typ": "JWT"
}
  • 这部分会被编码为Base64Url字符串,成为JWT的第一部分。

Base64Url字符串

Base64Url字符串是一种特殊的Base64编码方式,主要用于在URL和JSON等环境中安全地传输Base64编码的数据。它与标准的Base64编码有一些关键的区别,以下是详细介绍:

  1. 定义

Base64是一种编码方式,用于将二进制数据转换为ASCII字符串。Base64Url是Base64的一种变体,专门用于URL和JSON等环境,以避免在URL中出现特殊字符导致的问题。

  1. 标准Base64与Base64Url的区别
  • 字符集:

标准Base64:使用A-Z、a-z、0-9、+和/作为字符集,最后一个字符是=,用于填充。

Base64Url:为了适应URL环境,将+替换为-,将/替换为_,并且不使用=作为填充字符。

  • 填充字符
    • 标准Base64:使用=作为填充字符,以确保编码后的字符串长度是4的倍数。
    • Base64Url:不使用=作为填充字符,因此编码后的字符串长度可能不是4的倍数。
  1. 编码过程
  • 标准Base64编码
    1. 将输入数据分割成每3个字节一组。
    2. 将每组3个字节(共24位)转换为4个6位的单元。
    3. 将每个6位的单元映射到Base64字符集中的字符。
    4. 如果输入数据的长度不是3的倍数,使用=作为填充字符,使编码后的字符串长度成为4的倍数。
  • Base64Url编码
    1. 同样将输入数据分割成每3个字节一组。
    2. 将每组3个字节(共24位)转换为4个6位的单元。
    3. 将每个6位的单元映射到Base64Url字符集中的字符。
    4. 不使用=作为填充字符,因此编码后的字符串长度可能不是4的倍数。
  1. 优点
  • URL安全:Base64Url编码避免了在URL中出现+/等特殊字符,这些字符在URL中可能会被误解为运算符或分隔符。
  • 紧凑性:不使用填充字符=,使得编码后的字符串更加紧凑,适合在URL等环境中使用。
  1. 应用场景
  • JWT:在JWT中,Header和Payload部分通常使用Base64Url编码,以确保在URL和JSON环境中安全传输。
  • Web开发:在Web开发中,Base64Url编码常用于在URL中传递编码后的数据,避免特殊字符导致的问题。

通过这些特性,Base64Url编码在需要将数据安全地嵌入URL或JSON等环境时非常有用。

2.2 Payload(负载)

  • 存放实际需要传递的数据。它是一个JSON对象,可以包含多个声明(claim)。声明分为三类:

  • 注册声明:这些声明是预定义的,用于提供一组推荐的常用声明。例如:

    • iss(Issuer):发行者

    • exp(Expiration Time):过期时间

    • sub(Subject):主题,通常是用户ID等标识用户的信息

  • 公共声明:这些声明可以由开发者自定义,但为了避免冲突,应该在IANA JSON Web Token Registry中注册它们,或者使用公共的命名空间来避免冲突。

  • 私有声明:这些是为在各方之间共享信息而定制的声明,它们既不是注册声明也不是公共声明。

例如,一个Payload可能如下:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

这部分同样会被编码为Base64Url字符串,成为JWT的第二部分。

2.3 Signature(签名)

  • 用于验证消息的完整性和确保消息是由JWT的创建者发送的。签名的生成方式是使用编码后的Header和Payload,以及一个密钥(secret),通过Header中指定的算法进行签名。例如,对于HMAC SHA256算法,签名的生成方式如下:
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)
  • 签名部分也是Base64Url编码的,成为JWT的第三部分。
  • 最终,一个JWT看起来像这样:
xxxxx.yyyyy.zzzzz
  • 其中,xxxxx是Header的Base64Url编码,yyyyy是Payload的Base64Url编码,zzzzz是签名部分。

三、工作流程

3.1 身份验证场景

  • 当用户登录时,服务器会验证用户的凭证(如用户名和密码)。验证通过后,服务器会创建一个JWT并将其发送给用户。
  • 用户在随后的请求中将JWT包含在HTTP请求的Authorization头中发送给服务器。服务器会验证JWT的签名,如果验证通过,就会允许用户访问受保护的资源。
  • 由于JWT是自包含的,服务器不需要存储用户的会话信息,这使得JWT非常适合分布式系统,减少了服务器的存储压力。

3.2 信息交换场景

  • 当一个服务需要向另一个服务传递一些用户信息时,可以将这些信息放在JWT的Payload中。接收服务可以通过验证JWT的签名来确认信息的来源和完整性。

四、优缺点

优点

  • 无状态和可扩展性:由于JWT包含了所有必要的信息,服务器不需要存储用户的会话状态,这使得JWT非常适合分布式系统,可以轻松地扩展。
  • 易于跨域传递:JWT是一个紧凑的字符串,可以方便地在不同域之间传递,例如通过HTTP请求的头部。
  • 灵活的声明:可以包含各种声明来满足不同的需求,无论是身份验证信息还是其他业务相关的信息。

缺点

  • 安全性问题:虽然JWT的签名可以防止数据被篡改,但如果JWT被泄露,攻击者可以使用它来访问受保护的资源,直到JWT过期。因此,需要合理设置JWT的过期时间,并且在必要时可以使用HTTPS来保护JWT在传输过程中的安全。
  • 大小限制:由于JWT是通过HTTP头部传递的,如果负载部分过大,可能会导致性能问题。
  • 如果JWT的签名密钥泄露,攻击者确实可以伪造JWT的签名部分,从而创建看似有效的JWT。这会带来严重的安全风险,因为攻击者可以冒充合法用户访问受保护的资源。

jwt与jwt token

JWT(JSON Web Token)JWT Token 实际上是同一个概念的不同表述。它们指的是同一种技术,只是称呼方式略有不同。以下是对它们关系的详细解释:

定义

  • JWT(JSON Web Token):是一种开放标准(RFC 7519),用于在各方之间以JSON对象安全地传递信息。JWT通常用于身份验证和信息交换。
  • JWT Token:这是对JWT的另一种称呼,强调它是一个用于身份验证和信息交换的“令牌”(Token)。在实际使用中,人们常常会说“JWT Token”来指代一个具体的JWT。

文章作者: 司晓凯
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 司晓凯 !
  目录