一、定义
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编码有一些关键的区别,以下是详细介绍:
- 定义
Base64是一种编码方式,用于将二进制数据转换为ASCII字符串。Base64Url是Base64的一种变体,专门用于URL和JSON等环境,以避免在URL中出现特殊字符导致的问题。
- 标准Base64与Base64Url的区别
- 字符集:
标准Base64:使用A-Z、a-z、0-9、+和/作为字符集,最后一个字符是=,用于填充。
Base64Url:为了适应URL环境,将+替换为-,将/替换为_,并且不使用=作为填充字符。
- 填充字符:
- 标准Base64:使用
=
作为填充字符,以确保编码后的字符串长度是4的倍数。- Base64Url:不使用
=
作为填充字符,因此编码后的字符串长度可能不是4的倍数。
- 编码过程
- 标准Base64编码:
- 将输入数据分割成每3个字节一组。
- 将每组3个字节(共24位)转换为4个6位的单元。
- 将每个6位的单元映射到Base64字符集中的字符。
- 如果输入数据的长度不是3的倍数,使用
=
作为填充字符,使编码后的字符串长度成为4的倍数。- Base64Url编码:
- 同样将输入数据分割成每3个字节一组。
- 将每组3个字节(共24位)转换为4个6位的单元。
- 将每个6位的单元映射到Base64Url字符集中的字符。
- 不使用
=
作为填充字符,因此编码后的字符串长度可能不是4的倍数。
- 优点
- URL安全:Base64Url编码避免了在URL中出现
+
和/
等特殊字符,这些字符在URL中可能会被误解为运算符或分隔符。- 紧凑性:不使用填充字符
=
,使得编码后的字符串更加紧凑,适合在URL等环境中使用。
- 应用场景
- 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。