GitHub链接:Java_Code_template/Login at main · mao-design/Java_Code_template
1. 登录时发生什么?
用户输入:
用户名:admin
密码:123456后端验证成功。
生成两个 Token:
Access Token
例如:
AccessToken-A里面:
{
"username":"admin",
"type":"access",
"exp":"10:30"
}有效期:
30分钟用途:
访问接口
比如:
GET /user/info
Authorization: Bearer AccessToken-ARefresh Token
例如:
RefreshToken-A里面:
{
"username":"admin",
"type":"refresh",
"jti":"abc123",
"exp":"7天后"
}有效期:
7天用途:
换新的 Access Token
然后:
Refresh Token 存 Redis:
key:
refresh:admin:abc123
value:
RefreshToken-A此时:
客户端:
AccessToken-A
RefreshToken-A
Redis:
refresh:admin:abc123
|
↓
RefreshToken-A2. 平时访问接口怎么办?
比如:
10:05 请求:
GET /order/list带:
AccessToken-A流程:
请求
|
↓
JwtFilter
|
↓
解析 AccessToken-A
|
↓
检查:
签名正确?
有没有过期?
|
↓
通过
|
↓
Controller注意:
这里:
不看 Refresh Token
不查 Redis
不生成新 Token
因为 Access Token 还有效。
3. Access Token什么时候更新?
重点:
Access Token 不是每次请求更新。
只有:
Access Token过期的时候更新
例如:
登录:
10:00生成:
AccessToken-A
有效30分钟所以:
10:30
过期10:31 请求:
GET /user/info带:
AccessToken-A后端:
JwtFilter
|
↓
发现 exp < 当前时间
|
↓
ExpiredJwtException
|
↓
返回401返回:
{
"code":401,
"msg":"Token过期"
}4. 前端收到401之后怎么办?
前端发现:
AccessToken失效它不会让用户重新登录。
它调用:
POST /auth/refresh携带:
{
"refreshToken":"RefreshToken-A"
}5. Refresh接口做什么?
后端收到:
RefreshToken-A第一步:
验证 JWT:
jwtUtil.parseToken(refreshToken)检查:
是不是refresh类型?
有没有过期?
签名对不对?第二步:
查 Redis:
拿到:
refresh:admin:abc123看看:
Redis里面是不是:
RefreshToken-A如果:
一样:
说明:
这个RefreshToken有效6. 刷新成功后,更新什么?
这里是重点。
刷新成功:
后端生成:
新的 Access Token:
AccessToken-B新的 Refresh Token:
RefreshToken-B为什么两个都生成?
因为:
Access Token旧的已经过期
必须换。
Refresh Token也换
为了安全。
这叫:
Refresh Token Rotation
此时:
旧:
AccessToken-A ❌
RefreshToken-A ❌新:
AccessToken-B ✅
RefreshToken-B ✅Redis:
删除:
refresh:admin:abc123新增:
refresh:admin:def456
|
↓
RefreshToken-B返回前端:
{
"accessToken":"AccessToken-B",
"refreshToken":"RefreshToken-B"
}7. 前端收到新的Token怎么办?
替换本地:
原来:
localStorage
AccessToken-A
RefreshToken-A改成:
AccessToken-B
RefreshToken-B以后请求:
带:
AccessToken-B8. 流程图
登录
|
|
生成
|
+----------------+
| |
↓ ↓
AccessToken-A RefreshToken-A
30分钟 7天
|
|
访问接口
|
|
30分钟后
|
↓
AccessToken-A过期
|
↓
401
|
↓
调用refresh接口
|
↓
验证RefreshToken-A
|
↓
Redis检查
|
↓
生成
|
+----------------+
| |
↓ ↓
AccessToken-B RefreshToken-B
|
|
删除旧RefreshToken-A
|
↓
Redis保存RefreshToken-B
|
↓
返回前端
|
↓
替换旧Token