什么是 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-256typ: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 为例,签名过程分三步:
- 把
base64url(header) + "." + base64url(payload)拼成一个字符串 - 用密钥(secret)对这个字符串做 HMAC-SHA256 运算
- 结果再做一次 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 的内容并验证签名。
使用步骤:
- 把 JWT 字符串粘贴到输入框
- 工具自动解码 Header 和 Payload,以格式化 JSON 形式展示
- 如果是 HS256 算法,输入密钥即可验证签名是否正确
- 验证通过显示绿色标记,失败则提示签名不匹配
工具纯客户端运行,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