宝贝们好呀~今天 YuKi 想来聊聊 Web 开发里一个特别常用的「通行证」——JWT(JSON Web Token) 🔐✨
你有没有想过,登录一个网站之后,为什么刷新页面不会让你重新输入密码?为什么你可以在不同页面之间自由穿梭,服务器始终「记得」你是谁?
这背后,就是「认证状态管理」的魔法。而 JWT,是其中一种特别优雅的方案~
传统 Session 的烦恼
最早期,大家用 Session 来搞定这件事:
- 你登录后,服务器创建一个 Session,把用户 ID 存进去
- 服务器把 Session ID 通过 Cookie 发给你
- 之后每次请求,你带上这个 Cookie
- 服务器拿着 Session ID 去内存/Redis 里查你是谁
听起来还行对吧?但问题来了:
- ☁️ 多服务器架构:你有三台服务器,Session 存在第一台上,第二台不认识你——得搞 Redis 共享
- 🧠 内存开销:每个用户一个 Session,百万用户就是百万条记录
- 📱 移动端 / 跨域:Cookie 在 App 里不好使,跨域请求也不太方便
结论:Session 像一个「寄存处」——每次都要回去取。JWT 像一个「随身证件」——自己揣着就行!
JWT 的三段式结构
JWT 本质上就是一个经过签名的 JSON,分成三段,用 . 连接:
eyJhbGciOi...(Header).eyJzdWIiOi...(Payload).SflKxwR...(Signature)第一段:Header(头部)
告诉别人「我是怎么签名的」:
{ "alg": "HS256", "typ": "JWT"}然后用 Base64URL 编码一下,就变成了第一段。
第二段:Payload(负载)
这是真正「随身携带」的信息:
{ "sub": "1234567890", "name": "YuKi", "iat": 1717200000, "exp": 1717286400}常见字段:
| 字段 | 含义 | 说明 |
|---|---|---|
sub | Subject | 用户 ID |
iat | Issued At | 签发时间 |
exp | Expiration | 过期时间 |
iss | Issuer | 签发者 |
重要提醒:Payload 只是 Base64URL 编码,不是加密!任何人拿到 JWT 都能解码看到里面的内容。所以千万别把密码存进去!
第三段:Signature(签名)
这是 JWT 安全性的核心。签名是这样算出来的:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)服务器拿到 JWT 后,用同样的密钥重新算一遍签名,如果对得上——说明这个 Token 没被篡改过!
JWT 的完整流程
用户登录 → 服务器验证密码 → 生成 JWT(签名 + 设置过期时间) → 返回 JWT 给客户端
客户端请求 → 带上 Authorization: Bearer <JWT> → 服务器验证签名 ✓ → 检查过期时间 ✓ → 从 Payload 读取用户 ID → 执行业务逻辑整个过程不需要查数据库验证用户身份——因为 Payload 里已经带了用户 ID,签名保证了它没被篡改。这就是「无状态认证」的核心魅力!
JWT 的两大坑
坑一:Token 一旦签发,在过期前无法主动失效。 用户改密码了?旧 Token 在过期前依然有效!解决方案是维护一个「黑名单」(Redis),但要权衡——这又回到了有状态……
坑二:存储位置的选择。 存在 localStorage 容易受 XSS 攻击;存在 httpOnly Cookie 里可以防 XSS,但又可能受 CSRF 攻击。一般推荐:JWT 放 httpOnly Secure Cookie,再加 CSRF Token 防护。
什么时候该用 JWT?
✅ 微服务架构(服务间传递身份信息) ✅ 移动端 App(不依赖 Cookie) ✅ 单点登录(SSO) ✅ API 网关认证
❌ 纯服务端渲染的传统网站(Session 更简单)
好啦~今天的小课堂就到这里!JWT 本质上就是一份「自带签名的身份证」——轻量、无状态、跨平台。但记住:Payload 是透明的,别放敏感信息;还有,过期时间别设太长哦 🔐
下次想听 YuKi 讲什么呀?评论区告诉窝~ 💕✨
参考资料:RFC 7519、jwt.io