JSON Web Token (JWT) 解码器:检查 JWT 内容和声明

· 12分钟阅读

目录

理解 JSON Web Token

JSON Web Token(JWT)是一种紧凑、自包含的令牌,用于在各方之间以 JSON 对象的形式安全地传输信息。它们已成为现代 Web 应用程序、移动应用和微服务架构中身份验证和信息交换的事实标准。

与传统的基于会话的身份验证(用户数据存储在服务器上)不同,JWT 将数据直接嵌入令牌本身。这一根本差异使 JWT 非常适合无状态操作——服务器不需要维护会话存储或在每次请求时查询数据库来验证用户身份。

可以把 JWT 想象成数字护照。就像护照包含您的身份信息并通过全息图和水印进行加密保护一样,JWT 包含有关用户的声明,并经过加密签名以防止篡改。当您在边境检查站出示护照时,官员可以验证其真实性而无需致电您的祖国——同样,服务可以验证 JWT 而无需联系颁发服务器。

专业提示:JWT 在分布式系统和微服务架构中特别有用,在这些架构中维护集中式会话状态会造成瓶颈。每个服务都可以独立验证令牌,无需跨服务通信。

JWT 表现出色的常见场景包括:

JWT 的三部分结构

每个 JWT 由三个不同的部分组成,用句点(点)分隔。每个部分在令牌的功能和安全模型中都有特定的用途。当您看到 JWT 时,它看起来像这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

让我们分解每个组件:

头部

头部通常由两部分组成:令牌类型(即 JWT)和正在使用的签名算法,例如 HMAC SHA256 或 RSA。此信息告诉接收方如何处理和验证令牌。

解码后的头部如下所示:

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

载荷

载荷包含声明——关于实体(通常是用户)和附加元数据的陈述。声明分为三种类型:

声明类型 描述 示例
注册声明 JWT 规范推荐的预定义声明 issexpsubaud
公共声明 使用 JWT 的人定义的自定义声明,应具有抗冲突性 nameemailrole
私有声明 各方之间商定的自定义声明 departmentpermissions

典型的载荷可能如下所示:

{
  "sub": "1234567890",
  "name": "John Doe",
  "email": "[email protected]",
  "role": "admin",
  "iat": 1516239022,
  "exp": 1516242622
}

签名

签名是确保令牌未被篡改的加密封印。它是通过获取编码的头部、编码的载荷、密钥,并应用头部中指定的算法来创建的。

例如,如果使用 HMAC SHA256,签名的创建方式如下:

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

签名允许接收方验证 JWT 的发送者是否是其所声称的身份,以及消息在传输过程中是否未被更改。

为什么使用 JSON Web Token 解码器?

虽然 JWT 设计为机器可读,但开发人员在开发、调试和安全审计期间经常需要检查其内容。JWT 解码器将 Base64 编码的字符串转换为人类可读的 JSON,使您可以轻松了解令牌包含的信息。

以下是开发人员使用 JWT 解码器的主要原因:

开发和调试

在构建身份验证系统时,您需要验证令牌是否包含正确的声明并且格式正确。解码器让您可以快速检查令牌,而无需编写自定义代码或使用命令行工具。

例如,如果用户报告身份验证问题,您可以解码他们的 JWT 以检查 exp(过期)声明是否已过期或是否缺少必需的声明。

安全审计

安全团队使用 JWT 解码器分析令牌的潜在漏洞。他们可以检查:

集成测试

在与使用 JWT 身份验证的第三方 API 集成时,解码令牌可帮助您了解预期的格式和声明结构。当文档不完整或过时时,这尤其有用。

学习和教育

对于 JWT 新手开发人员,解码器提供关于三部分结构如何工作以及载荷更改如何影响最终令牌的即时视觉反馈。

快速提示:切勿将包含真实用户数据的生产 JWT 粘贴到在线解码器中。使用我们的 JWT 解码器工具,它完全在您的浏览器中处理令牌,不会将数据发送到任何服务器。

逐步解码过程

一旦您了解了这个过程,解码 JWT 就很简单了。以下是其底层工作原理:

步骤 1:拆分令牌

首先,在句点字符处拆分 JWT 字符串以分离三个部分:

const parts = token.split('.');
const header = parts[0];
const payload = parts[1];
const signature = parts[2];

步骤 2:Base64 解码

每个部分都是 Base64URL 编码的(Base64 的 URL 安全变体)。解码头部和载荷以获取 JSON 字符串:

const decodedHeader = atob(header);
const decodedPayload = atob(payload);

步骤 3:解析 JSON

将解码的字符串解析为 JSON 对象:

const headerObj = JSON.parse(decodedHeader);
const payloadObj = JSON.parse(decodedPayload);

步骤 4:检查内容

现在您可以检查声明和元数据。检查标准声明,例如:

使用我们的 JWT 解码器,整个过程会在您的浏览器中立即完成。只需粘贴您的令牌,即可立即看到解码的头部和载荷。

验证令牌的签名

解码 JWT 只是故事的一半——验证才是安全发生的地方。任何人都可以解码 JWT,因为它只是 Base64 编码的 JSON,但只有拥有正确密钥或公钥的各方才能验证签名。

为什么签名验证很重要

签名确保两个关键的安全属性:

  1. 完整性:令牌自签名以来未被修改
  2. 真实性:令牌是由拥有密钥的可信方创建的

如果没有签名验证,攻击者可以解码 JWT,更改载荷(也许将他们的权限从"用户"提升到"管理员"),重新编码它,然后使用修改后的令牌。签名可以防止这种攻击。

验证过程

要验证 JWT 签名,您需要:

验证过程使用令牌中的头部和载荷重新创建签名,然后将其与令牌中包含的签名进行比较。如果它们匹配,则令牌有效。

专业提示:始终在服务器端验证 JWT,切勿仅信任客户端验证。攻击者可以绕过客户端检查,但他们无法在没有密钥的情况下伪造有效签名。

常见签名算法

算法 类型 密钥类型 使用场景
HS256 HMAC 与 SHA-256 对称(共享密钥) 简单应用程序,同一方创建和验证
RS256 RSA 与 SHA-256 非对称(公钥/私钥对) 分布式系统,多个验证者
ES256

📚 You May Also Like