






















一、JWT 全称 JSON Web Token,说白了就是一段字符串,用点号分成三段:Header、Payload、Signature。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

JWT的三段结构:Header(算法类型)、Payload(用户信息)、Signature(签名),三部分Base64编码后用点号连接
JWT认证完整流程:用户登录→服务端签发Token→客户端存储→请求时带上Token→服务端验签登录成功 → 服务端签发 Token → 客户端保存(一般放 localStorage)→ 每次请求在 Header 里带上 `Authorization: Bearer <token>` → 服务端验签,从 Payload 取用户信息。全程不查数据库、不查 Redis,自给自足。 这就是"无状态"的意思。
二、JWT"无状态"的代价:四个致命场景
无状态听起来很美,上线后就知道了。
这四个场景加在一起,几乎是所有正经业务系统都会碰到的问题
三、为什么要把 Token 放 Redis
用户被踢下线时,把 token 加进黑名单。每次请求先查黑名单,在里面就拒。黑名单存哪?内存不行(多台服务器不共享,重启丢),数据库太慢(每个请求都查一次受不了),Redis 最合适 ——查询不到 1ms,分布式共享。
// 退出登录时,把 token 加入黑名单
publicvoidlogout(String token){
long expiration = jwtUtil.getExpiration(token);
long ttl = expiration - System.currentTimeMillis();
if (ttl > 0) {
redisTemplate.opsForValue().set(
"blacklist:" + token, "1", ttl, TimeUnit.MILLISECONDS
);
}
}
// 验证 token 时,先查黑名单
public boolean isTokenValid(String token){
if (redisTemplate.hasKey("blacklist:" + token)) {
returnfalse;
}
return jwtUtil.verify(token);
}
Redis 只存"已失效"的 token,平时没什么写入,查询也快。还有更彻底的方案:直接把 token 存 Redis,每次验证都去 Redis 查。 这和传统 Session 没太大区别,只是借了 JWT 格式当 Session ID 用。
四、双 Token 续期方案
Token 到期了,用户正在操作怎么办?
AccessToken 过期,前端用 RefreshToken 换新的,对用户无感。RefreshToken 存 Redis,用户改密码就删掉,自动让他下次操作时重新登录。
五、Redis 本身可靠吗
有人担心引入单点故障。Redis 的高可用方案跑了十几年:
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。