首页 >web前端 >js教程 >掌握 JWT(JSON Web 令牌):深入探讨

掌握 JWT(JSON Web 令牌):深入探讨

DDD
DDD原创
2025-01-21 20:37:10733浏览

JSON Web Token (JWT):跨域身份验证的热门方案

本文介绍了当下最流行的跨域身份验证解决方案——JSON Web Token (JWT) 的原理和使用方法。

一、跨域身份验证的挑战

互联网服务离不开用户身份验证。传统流程如下:

  1. 用户向服务器发送用户名和密码。
  2. 服务器验证成功后,将用户角色、登录时间等相关数据保存在当前会话中。
  3. 服务器返回一个 session_id 给用户,并将其写入用户的 Cookie。
  4. 用户后续每次请求,都会通过 Cookie 将 session_id 发送回服务器。
  5. 服务器收到 session_id 后,查找预保存的数据,从而识别用户身份。

此模型的扩展性差:单机环境没问题,但服务器集群或跨域面向服务的架构则需要会话数据共享,每台服务器都能读取会话。例如,网站 A 和网站 B 是同一家公司的关联服务,要求用户登录其中一个网站后,访问另一个网站也能自动登录。一种解决方案是持久化会话数据,将其写入数据库或其他持久层,各服务收到请求后从持久层请求数据。此方案架构清晰,但工作量较大,且持久层故障会导致单点故障。另一种方案是服务器根本不保存会话数据,所有数据保存在客户端,每次请求都发送回服务器。JWT 正是这种方案的代表。

二、JWT 的原理

JWT 的原理是服务器验证后生成一个 JSON 对象并返回给用户,例如:

<code class="language-json">{"name": "Alice", "role": "admin", "expiration time": "2024年7月1日0:00"}</code>

之后用户与服务器通信时需要回传此 JSON 对象,服务器完全根据此对象确定用户身份。为防止用户篡改数据,服务器生成此对象时会添加签名(细节后述)。服务器不再保存任何会话数据,即服务器变为无状态的,更容易实现扩展。

三、JWT 的数据结构

实际的 JWT 类似这样:

Mastering JWT (JSON Web Tokens): A Deep Dive

它是一个很长的字符串,由点 (.) 分隔成三个部分。注意 JWT 内部没有换行符,此处分行只是为了便于显示。JWT 的三个部分如下:

  • Header (头部)
  • Payload (有效载荷)
  • Signature (签名)

一行表示为:Header.Payload.Signature

Mastering JWT (JSON Web Tokens): A Deep Dive

下面分别介绍这三个部分。

3.1 Header (头部)

Header 部分是一个 JSON 对象,描述 JWT 的元数据,通常如下:

<code class="language-json">{"alg": "HS256", "typ": "JWT"}</code>

其中 alg 属性表示签名算法,默认为 HMAC SHA256 (HS256);typ 属性表示此令牌的类型,JWT 令牌统一写为 JWT。此 JSON 对象最终使用 Base64URL 算法转换为字符串(细节后述)。

3.2 Payload (有效载荷)

Payload 部分也是一个 JSON 对象,用于存储实际需要传输的数据。JWT 定义了 7 个官方字段可选:

  • iss (issuer):发行者
  • exp (expiration time):过期时间
  • sub (subject):主题
  • aud (audience):受众
  • nbf (Not Before):生效时间
  • iat (Issued At):签发时间
  • jti (JWT ID):序列号

除了官方字段,还可以自定义私有字段。例如:

<code class="language-json">{"name": "Alice", "role": "admin", "expiration time": "2024年7月1日0:00"}</code>

注意,JWT 默认不加密,任何人都可以读取,因此不要在此部分放置秘密信息。此 JSON 对象也需要使用 Base64URL 算法转换为字符串。

3.3 Signature (签名)

Signature 部分是前两部分的签名,用于防止数据篡改。首先需要指定一个密钥 (secret),此密钥只有服务器知道,不能泄露给用户。然后使用 Header 中指定的签名算法(默认为 HMAC SHA256)根据以下公式生成签名:

<code class="language-json">{"alg": "HS256", "typ": "JWT"}</code>

计算出签名后,将 Header、Payload 和 Signature 三部分组合成一个字符串,各部分之间用 "点" (.) 分隔,即可返回给用户。

3.4 Base64URL

如前所述,Header 和 Payload 的序列化算法是 Base64URL。此算法基本与 Base64 算法类似,但有一些细微差别。作为令牌,JWT 有时可能放在 URL 中(例如 api.example.com/?token=xxx),Base64 中的三个字符 、/ 和 = 在 URL 中有特殊含义,需要替换:= 被省略, 被替换为 -,/ 被替换为 _。这就是 Base64URL 算法。

四、JWT 的使用方法

客户端收到服务器返回的 JWT 后,可以将其存储在 Cookie 或 localStorage 中。之后客户端每次与服务器通信都需要携带此 JWT。可以将其放在 Cookie 中自动发送,但这无法跨域。更好的方法是将其放在 HTTP 请求头的 Authorization 字段中:

Authorization: Bearer

另一种方法是在跨域时将 JWT 放在 POST 请求的数据体中。

五、JWT 的几个特性

(1) JWT 默认不加密,但可以加密。生成原始 Token 后,可以用密钥再次加密。

(2) JWT 未加密的情况下,不能写入秘密数据。

(3) JWT 不仅可以用于身份验证,还可以用于信息交换。有效使用 JWT 可以减少服务器查询数据库的次数。

(4) JWT 最大的缺点是服务器不保存会话状态,无法在使用过程中撤销某个令牌或更改令牌的权限。也就是说,JWT 一旦发出,就一直有效直到过期,除非服务器部署额外逻辑。

(5) JWT 本身包含身份验证信息,一旦泄露,任何人都可以获得令牌的所有权限。为减少被盗,JWT 的有效期应设置得相对较短。对于一些更重要的权限,用户使用时应再次进行身份验证。

(6) 为减少被盗,JWT 不应使用 HTTP 协议明文传输,而应使用 HTTPS 协议传输。

Leapcell:最佳无服务器 Web 托管平台

Mastering JWT (JSON Web Tokens): A Deep Dive

最后,推荐一个部署 Web 服务的最佳平台:Leapcell

1. 多语言支持

  • 使用 JavaScript、Python、Go 或 Rust 开发。

2. 免费部署无限项目

  • 只按使用付费——无请求,无收费。

3. 无与伦比的成本效益

  • 按需付费,无空闲费用。
  • 例如:25 美元支持 694 万次请求,平均响应时间为 60 毫秒。

4. 简化的开发者体验

  • 直观的 UI,轻松设置。
  • 全自动 CI/CD 管道和 GitOps 集成。
  • 实时指标和日志记录,提供可操作的见解。

5. 轻松扩展和高性能

  • 自动扩展,轻松处理高并发。
  • 零运营开销——只需专注于构建。

Mastering JWT (JSON Web Tokens): A Deep Dive

在文档中了解更多信息!

Leapcell Twitter:https://www.php.cn/link/7884effb9452a6d7a7a79499ef854afd

以上是掌握 JWT(JSON Web 令牌):深入探讨的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn