Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
5c1b334028
|
|
@ -27,7 +27,7 @@ import io.jsonwebtoken.SignatureAlgorithm;
|
|||
|
||||
/**
|
||||
* token验证处理
|
||||
*
|
||||
*
|
||||
* @author bonus
|
||||
*/
|
||||
@Component
|
||||
|
|
@ -58,7 +58,7 @@ public class TokenService
|
|||
|
||||
/**
|
||||
* 获取用户身份信息
|
||||
*
|
||||
*
|
||||
* @return 用户信息
|
||||
*/
|
||||
public LoginUser getLoginUser(HttpServletRequest request)
|
||||
|
|
@ -75,16 +75,23 @@ public class TokenService
|
|||
String usernameFromJwt = (String) claims.get(Constants.JWT_USERNAME);
|
||||
String userKey = getTokenKey(uuid);
|
||||
LoginUser user = redisCache.getCacheObject(userKey);
|
||||
|
||||
if (StringUtils.isNull(user))
|
||||
{
|
||||
// login_tokens:{uuid} 已不存在:视为会话被挤下线或已失效
|
||||
// 为确保前端能提示“其他设备登录”,在能解析出用户名时一律标记
|
||||
// login_tokens:{uuid} 已不存在:需要区分是过期还是被挤下线
|
||||
if (StringUtils.isNotEmpty(usernameFromJwt))
|
||||
{
|
||||
request.setAttribute("forceLogoutByOtherDevice", Boolean.TRUE);
|
||||
String mappedUuid = redisCache.getCacheObject(getUserTokenKey(usernameFromJwt));
|
||||
if (StringUtils.isNotEmpty(mappedUuid) && !uuid.equals(mappedUuid))
|
||||
{
|
||||
// 用户名映射存在且指向其他uuid,说明是被其他设备挤下线
|
||||
request.setAttribute("forceLogoutByOtherDevice", Boolean.TRUE);
|
||||
}
|
||||
// 否则就是正常的token过期,不需要设置特殊标记
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 单端在线校验:username -> uuid 映射需要与当前token匹配
|
||||
String username = user.getUsername();
|
||||
String mappedUuid = redisCache.getCacheObject(getUserTokenKey(username));
|
||||
|
|
@ -142,7 +149,7 @@ public class TokenService
|
|||
|
||||
/**
|
||||
* 创建令牌
|
||||
*
|
||||
*
|
||||
* @param loginUser 用户信息
|
||||
* @return 令牌
|
||||
*/
|
||||
|
|
@ -164,7 +171,7 @@ public class TokenService
|
|||
|
||||
/**
|
||||
* 验证令牌有效期,相差不足20分钟,自动刷新缓存
|
||||
*
|
||||
*
|
||||
* @param loginUser 登录信息
|
||||
* @return 令牌
|
||||
*/
|
||||
|
|
@ -180,7 +187,7 @@ public class TokenService
|
|||
|
||||
/**
|
||||
* 刷新令牌有效期
|
||||
*
|
||||
*
|
||||
* @param loginUser 登录信息
|
||||
*/
|
||||
public void refreshToken(LoginUser loginUser)
|
||||
|
|
@ -202,7 +209,7 @@ public class TokenService
|
|||
|
||||
/**
|
||||
* 设置用户代理信息
|
||||
*
|
||||
*
|
||||
* @param loginUser 登录信息
|
||||
*/
|
||||
public void setUserAgent(LoginUser loginUser)
|
||||
|
|
@ -297,6 +304,9 @@ public class TokenService
|
|||
return getToken(ServletUtils.getRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据token获取登录用户信息
|
||||
*/
|
||||
public LoginUser getLoginUser(String token){
|
||||
if (StringUtils.isNotEmpty(token)){
|
||||
try
|
||||
|
|
@ -307,19 +317,23 @@ public class TokenService
|
|||
String usernameFromJwt = (String) claims.get(Constants.JWT_USERNAME);
|
||||
String userKey = getTokenKey(uuid);
|
||||
LoginUser user = redisCache.getCacheObject(userKey);
|
||||
|
||||
if (StringUtils.isNull(user))
|
||||
{
|
||||
// 若login_tokens无此uuid,检查用户名映射,若映射存在且指向其他uuid,则视为被其他设备挤下线
|
||||
// 若login_tokens无此uuid,检查用户名映射
|
||||
if (StringUtils.isNotEmpty(usernameFromJwt))
|
||||
{
|
||||
String mappedUuid = redisCache.getCacheObject(getUserTokenKey(usernameFromJwt));
|
||||
if (StringUtils.isNotEmpty(mappedUuid) && !uuid.equals(mappedUuid))
|
||||
{
|
||||
// 被其他设备挤下线
|
||||
return null;
|
||||
}
|
||||
// 否则是正常过期,返回null
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String username = user.getUsername();
|
||||
String mappedUuid = redisCache.getCacheObject(getUserTokenKey(username));
|
||||
if (StringUtils.isEmpty(mappedUuid) || !uuid.equals(mappedUuid))
|
||||
|
|
@ -351,4 +365,47 @@ public class TokenService
|
|||
}
|
||||
redisCache.setCacheObject(userTokenKey, uuid, expireTime, TimeUnit.MINUTES);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查token是否过期(新增方法)
|
||||
*
|
||||
* @param token token
|
||||
* @return true-过期, false-未过期
|
||||
*/
|
||||
public boolean isTokenExpired(String token) {
|
||||
try {
|
||||
Claims claims = parseToken(token);
|
||||
String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
|
||||
String userKey = getTokenKey(uuid);
|
||||
LoginUser user = redisCache.getCacheObject(userKey);
|
||||
return StringUtils.isNull(user);
|
||||
} catch (Exception e) {
|
||||
log.error("检查token过期状态异常'{}'", e.getMessage());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否被其他设备挤下线(新增方法)
|
||||
*
|
||||
* @param token token
|
||||
* @return true-被挤下线, false-未被挤下线
|
||||
*/
|
||||
public boolean isForceLogoutByOtherDevice(String token) {
|
||||
try {
|
||||
Claims claims = parseToken(token);
|
||||
String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
|
||||
String usernameFromJwt = (String) claims.get(Constants.JWT_USERNAME);
|
||||
|
||||
if (StringUtils.isNotEmpty(usernameFromJwt)) {
|
||||
String mappedUuid = redisCache.getCacheObject(getUserTokenKey(usernameFromJwt));
|
||||
// 如果用户名映射存在且指向其他uuid,说明是被挤下线
|
||||
return StringUtils.isNotEmpty(mappedUuid) && !uuid.equals(mappedUuid);
|
||||
}
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
log.error("检查是否被挤下线异常'{}'", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue