登录后的接口请求头里带着一长串 eyJhbGciOi... 开头的令牌,两个点把它分成三段——这就是 JWT(JSON Web Token)。它为什么能证明「你是你」?改一个字为什么会立刻失效?这篇拆开看。
| 段 | 内容 | 作用 |
|---|---|---|
| 第一段 Header | {"alg":"HS256","typ":"JWT"} 的 Base64URL | 声明签名算法 |
| 第二段 Payload | {"sub":"1001","exp":1770000000,...} 的 Base64URL | 存放用户信息与过期时间 |
| 第三段 Signature | 对前两段的 HMAC/RSA 签名 | 防篡改的核心 |
关键认知:前两段只是 Base64URL 编码,不是加密,任何人粘贴到解码工具里都能读到内容。所以 payload 里只能放不敏感的字段(用户 ID、角色、过期时间),绝不能放手机号、身份证。签名才是安全所在:服务端用只有自己知道的密钥对前两段计算签名,改了 payload 中任何一个字符,验签都会失败。
payload 里的 exp 是 Unix 时间戳(秒),服务端每次收到令牌都会比较它和当前时间。排查「为什么我登着登着就掉了」,先解码看 exp——常见坑有两种:一是令牌有效期本来就很短(如 2 小时),需要用刷新令牌机制续期;二是服务器时钟与标准时间偏差过大,导致刚签发的令牌「一出生就过期」。
Authorization: Bearer <token>,Bearer 后有一个空格;令牌被网关截断或前后带了引号都会导致解析失败;echo ' eyJwYXlsb2Fk...' | base64 -d 2>/dev/null(macOS 用 base64 -D),秒出 payload JSON;养成习惯:令牌只出现在环境变量和内存里,不进代码仓库、不进聊天记录。解完密钥相关的疑点后,到服务端把该测试用户的会话作废一次,确认旧令牌确实失效,才算排查闭环。
问:JWT 和 Session 有什么区别?
Session 状态存在服务端,JWT 把状态放在令牌里由客户端携带。JWT 的代价是「签发后无法主动作废」,所以高安全系统会配合黑名单或短有效期 + 刷新令牌。
问:Base64URL 和普通 Base64 有什么不同?
把 + 换成 -、/ 换成 _ 并去掉结尾的 =,避免在 URL 和 Header 里被转义破坏。