RUNWEBTOOLS
简体中文
网络与开发者

JWT 详解:结构、声明和如何解码

更新 2026-07-06

如果你用过现代 Web API,就见过 JWT —— 那些带两个点、出现在登录响应和 Authorization 头里的一长串乱码。它们看着不透明,但只要你知道结构,就出奇地好读。本指南讲清什么是 JSON Web Token、里面有什么、签名如何工作,以及要避免的安全错误。

JWT 是做什么用的

JSON Web Token(JWT) 是一种紧凑、自包含的方式,用来携带一组声明 —— 诸如“这是用户 42,他在 10:05 登录”这样的陈述。它的主要用途是身份验证:你登录后,服务器签发一个 JWT,你的应用在每次请求时把它带回,服务器就信任它,而不必每次都去会话存储里查你。因为令牌本身携带信息,所以被称为 无状态(stateless)

三个部分

每个 JWT 都是三段用点连接的 Base64URL 编码段:header.payload.signature

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MiJ9.3x9kQ...
└──── header ────┘ └── payload ──┘ └ signature ┘

1. 头部(Header)

关于令牌的元数据 —— 签名算法(alg,例如 HS256)和类型(typ: JWT)。解码后,它只是一小段 JSON:

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

2. 载荷(Payload)

声明 —— 实际的数据。有些名字是标准化的(称为注册声明):

  • sub —— 主体(subject),通常是用户 ID。
  • iss —— 签发者(issuer),谁创建了令牌。
  • aud —— 受众(audience),它是给谁的。
  • exp —— 过期时间(一个 Unix 时间戳)。
  • iat —— 签发时间(一个 Unix 时间戳)。

那些 expiat 的值是自 1970 年以来的秒数 —— 如果你需要把它们读成真实日期,时间戳转换器 会把它们变成人类可读的时间。

3. 签名(Signature)

签名是让令牌可信的东西。签发者拿着头部和载荷,用一个密钥生成一个加密签名。持有密钥的任何人都能验证头部和载荷没有被篡改 —— 只要改动载荷里的一个字符,签名就不再匹配。

最重要要理解的一点

JWT 是被签名的,不是被加密的。 头部和载荷只是被 Base64URL 编码,这意味着 任何人 都能解码并读取它们 —— 无需密钥。签名防止 篡改,而不是 读取

实际后果:永远不要把机密放进 JWT 载荷。没有密码、没有信用卡号、没有私密数据 —— 假设载荷是公开的。你可以把任意令牌粘进我们的 JWT 解码器 亲自确认,它会即时读出头部和声明,全程在你的浏览器中(令牌绝不离开你的设备)。底层不过是 Base64 解码 —— 解码器只是替你省了这些步骤。

验证 vs. 解码

这是两种不同的动作,把它们搞混是一个真实的安全漏洞。解码 读取载荷 —— 任何人都能做,且什么也证明不了。验证 用密钥检查签名,确认令牌是真实且未被改动的。服务器在信任之前必须 验证 每一个令牌;只解码不是身份验证。

常见陷阱

  • 信任一个未经验证的令牌 —— 在依据声明行动前,务必在服务器端检查签名。
  • 忽略过期 —— 尊重 exp;一个过期的令牌应当被拒绝。
  • 把敏感数据存进载荷 —— 它对任何人可读。
  • `alg: none` 陷阱 —— 一些库曾经接受声称“无签名”的令牌。拒绝它们,并锁定预期的算法。

理解这些,JWT 就从吓人的字符串变成一个简单、透明的格式:可读的声明,由一个你必须在信任前验证的签名来保护。

更多 网络与开发者

查看全部 网络与开发者 指南 →

本指南提到的工具