接口返回的 token 往往是一长串看不懂的字符,中间用两个点分成三段。这就是 JWT,一种用于传递声明的开放标准。看着像加密后的密文,实际上它根本没有加密——前两段只是编码,任何人拿到都能读出来。搞清楚这个区别,很多关于 JWT 的误解就自然消失了。
三段各自是什么
第一段是 Header,说明令牌类型和签名算法,通常写明用的是 HS256 还是 RS256。第二段是 Payload,存放实际要传递的声明,比如用户标识、角色、过期时间。第三段是 Signature,用前两段内容加上密钥算出来的一串校验值。三段之间用点号连接,整体是一串可打印字符,方便放在 HTTP 头里传输。
编码不等于加密
前两段用的是 Base64Url 编码,这是为了让二进制数据能安全地在 URL 里传输,本身不提供任何保密性。把 token 中间那段粘到Base64解码工具里,里面的用户 ID、权限、过期时间立刻原形毕露。所以任何敏感信息都不该放进 Payload——密码、身份证号、手机号放进去,等于直接对外公开。
签名才是安全的关键
签名的作用是防篡改,不是防读取。服务端收到 token 后,用同样的算法和密钥对前两段重新算一遍,比对结果是否和第三段一致,一致才说明内容没被改过。这意味着密钥一旦泄露,攻击者就能签发任意内容的令牌,所以密钥必须妥善保管,且不同环境要用不同密钥。
几个高频误区
最典型的是把 JWT 当 session 用,塞进大量业务数据,导致每次请求都要传输很长的字符串。正确做法是只放必要标识,其余信息服务端按需查询。第二个误区是设置超长的有效期,token 一旦发出在过期前无法主动失效,有效期越长风险越大。第三是误以为换个哈希算法就算加密,用MD5加密工具算个摘要当签名,在密钥泄露面前毫无作用。
排查问题的实用做法
接口报 401 时,先把 token 解析出来看看,多数问题一眼就能定位:过期时间是否已经过了,签发方和接收方填的是不是同一个,算法名称有没有拼写错误。解析时注意看 Payload 里的时间字段用的是秒级时间戳,别和毫秒级搞混,差了一千倍会算出离谱的过期时间,这类错误在跨语言对接时特别常见。