fix: 修改刷新token逻辑
This commit is contained in:
@@ -47,6 +47,9 @@ public class RefreshTokenServiceImpl implements RefreshTokenService {
|
||||
|
||||
@Override
|
||||
public String create(String userId) {
|
||||
if (userId == null || userId.isBlank()) {
|
||||
throw new BusinessException(ErrorCode.BAD_REQUEST, "用户ID不能为空");
|
||||
}
|
||||
// 先清除该用户之前的 refresh token,确保一个用户只有一个有效 token
|
||||
String oldToken = get(USER_KEY_PREFIX + userId);
|
||||
if (oldToken != null) {
|
||||
@@ -78,21 +81,30 @@ public class RefreshTokenServiceImpl implements RefreshTokenService {
|
||||
@Override
|
||||
public String rotate(String oldToken) {
|
||||
String userId = validate(oldToken);
|
||||
delete(KEY_PREFIX + oldToken);
|
||||
// 先删反向映射,再删正向映射:
|
||||
// 若反向映射删除失败,正向映射仍存在,调用方可重试;
|
||||
// 若反向已删除而正向删除失败,正向映射仍存在,重试仍可通过。
|
||||
delete(USER_KEY_PREFIX + userId);
|
||||
delete(KEY_PREFIX + oldToken);
|
||||
log.debug("旧刷新令牌已删除: userId={}", userId);
|
||||
return create(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void revoke(String token) {
|
||||
if (token != null && !token.isBlank()) {
|
||||
if (token == null || token.isBlank()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String userId = get(KEY_PREFIX + token);
|
||||
if (userId != null) {
|
||||
delete(USER_KEY_PREFIX + userId);
|
||||
}
|
||||
delete(KEY_PREFIX + token);
|
||||
log.debug("刷新令牌已撤销");
|
||||
} catch (BusinessException e) {
|
||||
// 登出时 Redis 不可用,记录日志后放行,不影响用户登出
|
||||
log.warn("撤销刷新令牌失败(Redis 不可用),跳过清理: token={}", token, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,6 +122,9 @@ public class RefreshTokenServiceImpl implements RefreshTokenService {
|
||||
|
||||
/**
|
||||
* 从 Redis 读取字符串(读取时续期)
|
||||
*
|
||||
* @return 值,key 不存在时返回 null
|
||||
* @throws BusinessException Redis 操作失败时抛出
|
||||
*/
|
||||
private String get(String key) {
|
||||
try {
|
||||
@@ -120,18 +135,21 @@ public class RefreshTokenServiceImpl implements RefreshTokenService {
|
||||
return value;
|
||||
} catch (Exception e) {
|
||||
log.error("查询缓存失败: key={}", key, e);
|
||||
return null;
|
||||
throw new BusinessException(ErrorCode.INTERNAL_ERROR, "刷新令牌操作失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 Redis 删除 key
|
||||
*
|
||||
* @throws BusinessException Redis 操作失败时抛出
|
||||
*/
|
||||
private void delete(String key) {
|
||||
try {
|
||||
stringRedisTemplate.delete(key);
|
||||
} catch (Exception e) {
|
||||
log.error("删除缓存失败: key={}", key, e);
|
||||
throw new BusinessException(ErrorCode.INTERNAL_ERROR, "刷新令牌操作失败");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user