跳到主要内容
编码转换2026-07-09Begin5 分钟阅读

JWT 详解:结构解析、签名验证与安全实践

什么是 JWT

JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用之间安全传递信息。它把数据编码成一个紧凑的字符串,可以放在 HTTP 请求头、URL 参数或 Cookie 里传输。

两个最典型的使用场景:

  • 用户认证:用户登录后,服务器签发一个 JWT,客户端在后续请求中携带它来证明身份。相比传统 Session,JWT 不需要在服务端存储会话状态,天然适合分布式和微服务架构。
  • 信息交换:JWT 可以携带签名,接收方能验证内容没被篡改。这让它适合在服务之间传递可信数据,比如 OAuth2 的 access token。

JWT 的三段式结构

一个 JWT 长这样,三段用 . 分隔:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

三段分别是 Header、Payload、Signature,每一段都是 Base64URL 编码的 JSON。

第一段:Header(头部)

解码后是一个 JSON 对象,说明 token 的类型和签名算法:

{
  "alg": "HS256",
  "typ": "JWT"
}
  • alg:签名算法,HS256 表示 HMAC + SHA-256
  • typ:token 类型,固定为 JWT

第二段:Payload(载荷)

存放实际数据,也就是声明(Claims)。解码后:

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

常见的标准声明(RFC 7519 定义):

字段含义说明
iss签发者token 是谁签发的
sub主体通常存用户 ID
aud接收方token 是给谁的
exp过期时间超过此时间 token 失效
iat签发时间token 的签发时间戳
nbf生效时间在此时间之前 token 不可用

你也可以加自定义字段,比如 name、role、email。

第三段:Signature(签名)

用来验证 token 没被篡改,下面单独讲。

签名验证原理

以最常用的 HS256 为例,签名过程分三步:

  1. 把 base64url(header) + "." + base64url(payload) 拼成一个字符串
  2. 用密钥(secret)对这个字符串做 HMAC-SHA256 运算
  3. 结果再做一次 Base64URL 编码,得到 signature
HMACSHA256(
  base64url(header) + "." + base64url(payload),
  secret
)

验证时,服务器拿到 token 后重复同样的计算,然后比对签名是否一致。因为攻击者不知道密钥,改了 Payload 也无法生成正确的签名,所以签名能防篡改。

有个细节值得注意:Base64URL 和普通 Base64 不一样。Base64URL 把 + 换成 -、/ 换成 _,并且去掉末尾的 = 填充。这样 token 可以安全放进 URL,不会被特殊字符干扰。

常见安全陷阱

alg: none 漏洞

JWT 的 Header 里有个 alg 字段,告诉服务器用什么算法验证。有些早期库的实现直接信任这个字段。如果攻击者把 alg 改成 none,再去掉签名段,部分库会跳过验证直接放行。

防御办法:服务端写死允许的算法列表(比如只接受 HS256),不要相信 token 自己声明的算法。

密钥强度

HS256 的安全性完全取决于密钥。密钥太短或太简单(比如 "secret"、"123456"),攻击者可以用字典爆破出密钥,然后伪造任意 token。

建议:密钥至少 32 字节,用随机生成的字符串,不要硬编码在代码仓库里。

过期时间设置

exp 声明控制 token 的有效期。设太长(比如一年),一旦泄露损失很大。设太短,用户又要频繁重新登录。

常见做法是 access token 设 15 到 30 分钟,搭配一个 refresh token(7 到 30 天)来续期。

单位必须是 Unix 秒。签发端误用毫秒、验证端按秒比较,会出现「刚签发就过期」或相对时间错乱——完整排查见 JWT exp/nbf 时钟漂移。生产校验请留 30–60 秒 leeway 吸收 NTP 抖动。

和 HTTPS 证书分开排查

TLS 证书回答「连的是不是目标站」;JWT 回答「这个请求的身份声明」。证书红屏走 证书解码 / 证书链不完整;401 走本文与解码器。两者同时出现时先分开复现。

存储位置:Cookie 还是 LocalStorage

这是个老问题,两种方案各有取舍:

  • LocalStorage:实现简单,前端可以自由读取。缺点是容易受 XSS 攻击窃取。
  • HttpOnly Cookie:JavaScript 无法读取,能防 XSS。但要配合 SameSite 属性防 CSRF。

对安全要求高的系统,优先用 HttpOnly + Secure + SameSite=Strict 的 Cookie。

如何使用在线工具

ToolVault 工具匣 的 JWT 解码工具 可以帮你快速查看 JWT 的内容并验证签名。

使用步骤:

  1. 把 JWT 字符串粘贴到输入框
  2. 工具自动解码 Header 和 Payload;下方时间轴展示 exp/iat/nbf 的 UTC 与相对偏移
  3. 若 Header 为 alg=none,会出现红色警示(未签名令牌)
  4. HS256 可输入密钥做本地验签;RS256/JWKS 请在服务端完成

工具纯客户端运行,token 不会上传。大整数 claims(如雪花 ID)按无损路径展示,避免尾数被 IEEE754 舍入。

实现注记 / Implementer's note

解码与 HS256 校验都在浏览器完成;时间轴是展示层(含毫秒量级启发式),不代替你的签发代码。Copy 固定在工具栏,避免被时间信息挡住主操作。与证书工具相同:不代你出站拉取远端材料。

FAQ

JWT 和 Session 有什么区别?

Session 是有状态的,服务器要存每个用户的会话信息。JWT 是无状态的,信息都在 token 里,服务器只需要密钥就能验证。Session 方便主动注销,JWT 天然适合分布式架构。

签名能被破解吗?

HS256 用的是 HMAC-SHA256,算法本身是安全的。风险出在密钥上。密钥足够长且随机,暴力破解不现实。密钥如果是 "secret" 这种弱口令,几秒就能破。

看场景。需要防 XSS 用 HttpOnly Cookie,需要前端读取用 LocalStorage。不管哪种,都要配合 HTTPS 传输。

JWT 能加密吗?

标准 JWT 只签名不加密,Payload 是 Base64URL 编码,任何人都能解码看到内容。如果需要保密,用 JWE(JSON Web Encryption)标准。

相关阅读

感谢阅读这篇 ToolVault 工具匣 技术文章。更多免费本地工具见 首页。