JWT 可以把它理解成一种**“能自带身份信息、还能防篡改的通行证”**。
JWT 是什么
JWT 全名是 JSON Web Token。
用户登录成功后,服务器会发给前端一串字符串,长这样:
1 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 |
它通常由三部分组成,用 . 分隔:
1 | Header.Payload.Signature |
1. Header:说明怎么签名
1 | { |
意思是:这是 JWT,使用 HS256 算法签名。
2. Payload:存放信息
1 | { |
这里可以放用户 ID、角色、过期时间等。
注意:Payload 只是 Base64URL 编码,不是加密。任何拿到 JWT 的人都能看到里面的数据。
所以千万别放密码、银行卡号之类的敏感信息。
3. Signature:防止被篡改
服务器用密钥对前两部分进行签名,大致相当于:
1 | 签名 = HMACSHA256( |
假如有人偷偷把:
1 | "role": "user" |
改成:
1 | "role": "admin" |
因为他不知道服务器的密钥,无法生成正确签名,服务器验证时就会发现 JWT 被改过。
JWT 登录流程
假设你登录一个网站:
1 | 1. 用户提交账号密码 |
请求时通常放在 HTTP Header 中:
1 | Authorization: Bearer <你的JWT> |
这里的 Bearer 可以理解为:谁拿着这个令牌,谁就被当作对应用户。
所以 JWT 一旦泄露,别人可能直接冒充你。
JWT 和 Session 的区别
Session
服务器保存登录状态:
1 | sessionId -> 用户信息 |
浏览器只保存 sessionId。
JWT
用户信息放在 Token 里,服务器一般不需要保存会话状态。
1 | JWT -> 自带用户信息和签名 |
可以粗略理解成:
1 | Session:服务器拿着花名册 |
JWT 的优点
- 适合前后端分离
- 适合多个服务之间传递身份
- 服务器不一定需要保存 Session
- 移动端、网页端都容易使用
JWT 的缺点
- 签发后不容易立即作废
- Token 泄露后可能被冒用
- Payload 不能存敏感数据
- Token 过大会增加每次请求的流量
- 不合理地存进
localStorage,可能增加 XSS 攻击下的泄露风险
Access Token 和 Refresh Token
实际项目一般不会只发一个永久 JWT,而是使用两个令牌:
1 | Access Token:有效期短,比如 15 分钟 |
流程是:
1 | Access Token 过期 |
这样即使 Access Token 泄露,攻击者能使用的时间也比较短。
一句话记忆
JWT 是服务器签发的、防篡改但通常不加密的身份令牌。
最重要的三个点:
1 | 能看见内容 |
所以 JWT 不是“加密身份证”,更像是带防伪签名的电子通行证。