JWT 深度解析:结构、流程、优劣与应用全景指南

JWT 是 JSON Web Token 的缩写,它是一种基于 JSON 的开放标准(RFC 7519),用于在网络应用程序之间安全地传输信息。以下是关于 JWT 的详细介绍:

一、JWT 结构详解

1.头部(Header)

头部通常由两部分组成:令牌的类型(即 JWT)和使用的签名算法,例如 HMAC SHA256 或者 RSA。以下是一个 JSON 格式的头部示例:

{
    "alg": "HS256",
    "typ": "JWT"
}

这个 JSON 对象会使用 Base64Url 编码,生成一个字符串作为 JWT 的第一部分。Base64Url 编码与普通的 Base64 编码类似,但它对 URL 更友好,会将+替换为-/替换为_,并去掉末尾的=

2.载荷(Payload)

载荷部分包含声明(Claims),声明是关于实体(通常是用户)和其他数据的声明。声明分为三种类型:

①.注册声明:这些是一组预定义的声明,不是强制要求的,但推荐使用。常见的注册声明有:

  • iss(Issuer):签发者,标识 JWT 的签发实体。
  • sub(Subject):主题,通常是用户的唯一标识。
  • aud(Audience):受众,标识 JWT 的接收方。
  • exp(Expiration Time):过期时间,指定 JWT 的过期时间戳,超过这个时间,JWT 将失效。
  • nbf(Not Before):生效时间,指定 JWT 开始生效的时间戳,在这个时间之前,JWT 不可用。
  • iat(Issued At):签发时间,指定 JWT 的签发时间戳。
  • jti(JWT ID):JWT 的唯一标识符,用于防止 JWT 被重复使用。

②.公开声明:这些是在同意使用的各方之间定义的声明,通常是为了传递用户的自定义信息,例如用户的角色、权限等。

③.私有声明:这些是在同意使用的各方之间定义的声明,用于在这些特定的各方之间共享信息。

以下是一个载荷的示例:

{
    "sub": "1234567890",
    "name": "John Doe",
    "iat": 1516239022,
    "exp": 1516242622
}

同样,这个 JSON 对象也会使用 Base64Url 编码,生成 JWT 的第二部分。

3.签名(Signature)

要创建签名部分,需要使用编码后的头部、编码后的载荷、一个密钥(secret)和头部中指定的签名算法。例如,如果使用的是 HMAC SHA256 算法,签名将按以下方式创建:

import hmac
import hashlib
import base64

header = '{"alg": "HS256", "typ": "JWT"}'
payload = '{"sub": "1234567890", "name": "John Doe", "iat": 1516239022, "exp": 1516242622}'
secret = 'your-256-bit-secret'

# Base64Url编码头部和载荷
encoded_header = base64.urlsafe_b64encode(header.encode('utf-8')).rstrip(b'=').decode('utf-8')
encoded_payload = base64.urlsafe_b64encode(payload.encode('utf-8')).rstrip(b'=').decode('utf-8')

# 拼接编码后的头部和载荷
signing_input = f'{encoded_header}.{encoded_payload}'

# 创建签名
signature = hmac.new(secret.encode('utf-8'), signing_input.encode('utf-8'), hashlib.sha256).digest()
encoded_signature = base64.urlsafe_b64encode(signature).rstrip(b'=').decode('utf-8')

# 最终的JWT
jwt = f'{encoded_header}.{encoded_payload}.{encoded_signature}'
print(jwt)

签名用于验证消息在传输过程中没有被更改,并且在使用私钥签名的情况下,还可以验证 JWT 的发送者的身份。

二、JWT 工作流程

1.客户端登录
  • 用户在客户端输入用户名和密码,客户端将这些信息发送到服务器进行身份验证。
  • 服务器验证用户名和密码的正确性,如果验证通过,服务器会根据用户的信息生成一个 JWT。
2.服务器生成 JWT
  • 服务器使用用户的信息(如用户 ID、角色等)作为载荷,选择合适的签名算法和密钥,生成 JWT。
  • 服务器将生成的 JWT 返回给客户端。
3.客户端存储和使用 JWT
  • 客户端接收到 JWT 后,通常会将其存储在本地,例如使用浏览器的localStoragesessionStorage
  • 在后续的请求中,客户端会将 JWT 包含在请求头中,通常使用Authorization头,格式为Bearer <JWT>
4.服务器验证 JWT
  • 服务器接收到请求后,会从请求头中提取 JWT。
  • 服务器使用相同的密钥和签名算法对 JWT 进行验证,检查签名是否有效、JWT 是否过期等。
  • 如果验证通过,服务器会从载荷中获取用户的信息,根据这些信息授权用户访问相应的资源。

三、JWT 的优缺点

1.优点
  • 无状态性:服务器不需要在会话中存储用户的状态信息,这使得服务器可以更容易地进行扩展,例如使用负载均衡器将请求分发到多个服务器上。
  • 跨域支持:由于 JWT 是通过 HTTP 头传输的,它可以很容易地在不同的域之间使用,适合于前后端分离的应用程序。
  • 安全性高:JWT 使用签名和加密技术来确保数据的完整性和安全性,防止数据被篡改和伪造。
  • 可扩展性强:可以在载荷中添加自定义的声明,以满足不同的业务需求。
2.缺点
  • 令牌体积较大:由于 JWT 包含了所有必要的信息,当载荷中的信息较多时,JWT 的体积会比较大,增加了网络传输的负担。
  • 无法中途撤销:一旦 JWT 被签发,在其过期之前,服务器无法主动撤销它。如果需要实现撤销功能,需要额外的机制,例如使用黑名单。
  • 安全风险:如果密钥泄露,攻击者可以伪造 JWT,从而获得用户的权限。因此,密钥的管理非常重要。

四、JWT 的应用场景

1.身份验证

在单页应用(SPA)、移动应用等场景中,JWT 常用于用户登录后的身份验证。用户登录成功后,服务器返回 JWT 给客户端,客户端在后续的请求中携带该令牌,服务器通过验证令牌来确定用户的身份和权限。

2.单点登录(SSO)

在多个相关的应用系统中,用户只需要在一个系统中登录一次,就可以访问其他相互信任的系统,而无需再次输入用户名和密码。JWT 可以作为在不同系统之间传递用户身份信息的载体,实现单点登录的功能。

3.API 授权

当应用程序需要调用其他第三方 API 时,可以使用 JWT 来进行授权。将包含授权信息的 JWT 发送给 API 服务器,API 服务器验证令牌的有效性后,允许应用程序访问相应的资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程在手天下我有

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值