Skip to content
encode

什么是 JWT

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

两个最典型的使用场景:

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

JWT 的三段式结构

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

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

三段分别是 HeaderPayloadSignature,每一段都是 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 不可用 |

你也可以加自定义字段,比如 nameroleemail

第三段: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 天)来续期。

存储位置:Cookie 还是 LocalStorage

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

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

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

如何使用在线工具

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

使用步骤:

  1. 把 JWT 字符串粘贴到输入框
  2. 工具自动解码 Header 和 Payload,以格式化 JSON 形式展示
  3. 如果是 HS256 算法,输入密钥即可验证签名是否正确
  4. 验证通过显示绿色标记,失败则提示签名不匹配

工具纯客户端运行,token 数据不会发送到任何服务器,关闭页面即被丢弃。

FAQ

JWT 和 Session 有什么区别?

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

签名能被破解吗?

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

token 存 Cookie 还是 LocalStorage?

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

JWT 能加密吗?

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


本文由 DevToolkit Pro 提供。更多开发者工具请访问 首页


← Back to Blog