JWT:那些长字符串里到底是什么
深入解析JSON Web Token的三段式结构、签名验证机制和有效载荷内容。了解JWT在身份认证中的工作原理,避免令牌泄露等常见安全错误。
你在认证系统中看到这样的字符串:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U。
那是什么?这是JWT——三个用点分隔的Base64编码块。你可以不需要任何特殊密钥就读取它。
三个部分
Header: 算法和token类型
{"alg": "HS256", "typ": "JWT"}
Payload: 实际数据(声明)
{"sub": "1234567890", "name": "John", "iat": 1516239022}
Signature: 验证没有被篡改
JWT不是加密的
这是重要的一点。任何人都可以解码JWT并读取其内容。Base64是编码,不是加密。
不要把秘密放在JWT中。用户ID、权限、过期时间——可以。密码、信用卡、私密数据——绝对不行。
标准声明
iss — 发行者。谁创建了这个token。
sub — 主体。通常是用户ID。
exp — 过期时间。Unix时间戳,token何时失效。
iat — 发行时间。token何时被创建。
aud — 受众。谁应该接受这个token。
自定义声明也可以。添加你的应用需要的任何数据。
签名如何工作
签名证明token没有被修改。
服务器创建token → 用密钥签名 → 发送给客户端。 客户端发送token回来 → 服务器验证签名 → 信任内容。
如果有人更改有效载荷,签名就不匹配。服务器拒绝它。
但服务器必须验证签名。没有验证的JWT是安全剧场。
常见安全错误
不验证签名。 有些代码解码JWT而不检查签名。任何人都可以伪造token。
使用弱密钥。 secret123不是秘密。使用长的随机字符串。
忽略过期时间。 总是检查exp。Token应该有短的生命周期。
算法混淆。 alg字段说明如何验证。如果你的代码信任header,攻击者可以将其设置为none并跳过验证。
存储敏感数据。 任何有token的人都可以读取有效载荷。把秘密保存在服务器端。
何时使用JWT
无状态认证。 服务器不需要存储会话。token包含所需的一切。
微服务。 服务可以验证token而不调用认证服务器。
单点登录。 跨域共享认证。
何时不使用JWT
简单应用。 会话cookie更简单,更难搞砸。
需要立即撤销。 JWT在过期前有效。撤销需要额外的基础设施。
大有效载荷。 每个请求都携带完整token。大token意味着更多带宽。
刷新Token
访问token应该是短期的(几分钟到几小时)。刷新token在不重新认证的情况下获取新访问token。
安全存储刷新token。它们是长期的且强大的。
JWT很方便但需要小心。理解它们包含什么,正确验证签名,设置短过期时间,永远不要把敏感数据放在有效载荷中。