|
|
@ -16,20 +16,24 @@ import javax.servlet.http.HttpServletRequest;
|
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
|
|
|
|
|
|
|
|
@Slf4j
|
|
|
|
@Slf4j
|
|
|
|
public class JwtInterceptor implements HandlerInterceptor {
|
|
|
|
public class JwtInterceptor implements HandlerInterceptor {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final ConcurrentHashMap<Object, JWT> singleLoginTokenCacheMap = new ConcurrentHashMap<>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
|
|
|
|
|
|
|
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
|
|
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
|
|
|
//请求消息头获取用户ID
|
|
|
|
//请求消息头获取用户ID
|
|
|
|
String token = request.getHeader("token");
|
|
|
|
String token = request.getHeader("token");
|
|
|
|
if (StrUtil.isBlank(token)) {
|
|
|
|
if (StrUtil.isBlank(token)) {
|
|
|
|
// 如果是swagger来的接口,说明这里是测试的,会伪造一个用户
|
|
|
|
// 如果是swagger来的接口,说明这里是测试的,会伪造一个用户
|
|
|
|
if (StrUtil.isNotBlank(request.getHeader("Knife4j-Gateway-Code"))) {
|
|
|
|
if (StrUtil.isNotBlank(request.getHeader("Knife4j-Gateway-Code"))) {
|
|
|
|
token = devActiveUser();
|
|
|
|
cacheAuth(JWTUtil.parseToken(devActiveUser()));
|
|
|
|
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
throw new BusinessException("当前用户未登录", HttpStatus.UNAUTHORIZED.value());
|
|
|
|
throw new BusinessException("当前用户未登录", HttpStatus.UNAUTHORIZED.value());
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -38,6 +42,8 @@ public class JwtInterceptor implements HandlerInterceptor {
|
|
|
|
JWT jwt = JWTUtil.parseToken(token);
|
|
|
|
JWT jwt = JWTUtil.parseToken(token);
|
|
|
|
// 校验token是否过期,如果过期了,需要提示过期重新登录
|
|
|
|
// 校验token是否过期,如果过期了,需要提示过期重新登录
|
|
|
|
checkTokenExpire(jwt);
|
|
|
|
checkTokenExpire(jwt);
|
|
|
|
|
|
|
|
// 校验是否重复登录
|
|
|
|
|
|
|
|
checkSingleLogin(jwt);
|
|
|
|
cacheAuth(jwt);
|
|
|
|
cacheAuth(jwt);
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -60,6 +66,26 @@ public class JwtInterceptor implements HandlerInterceptor {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void checkSingleLogin(JWT currentJwt) {
|
|
|
|
|
|
|
|
Object id = currentJwt.getPayload("id");
|
|
|
|
|
|
|
|
JWT singleLoginTokenCache = singleLoginTokenCacheMap.get(id);
|
|
|
|
|
|
|
|
// 然后将当前的expireTime和singleLoginTokenCache进行比较
|
|
|
|
|
|
|
|
Object expireTime = singleLoginTokenCache.getPayload("expireTime");
|
|
|
|
|
|
|
|
long singleLoginTokenCacheExpireTime = Long.parseLong(String.valueOf(expireTime));
|
|
|
|
|
|
|
|
Object currentJwtExpireTimeObject = currentJwt.getPayload("expireTime");
|
|
|
|
|
|
|
|
long currentJwtExpireTime = Long.parseLong(String.valueOf(currentJwtExpireTimeObject));
|
|
|
|
|
|
|
|
if (singleLoginTokenCacheExpireTime == currentJwtExpireTime) {
|
|
|
|
|
|
|
|
// 如果相等,说明这个token就是最新的,直接放行
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
} else if (currentJwtExpireTime > singleLoginTokenCacheExpireTime) {
|
|
|
|
|
|
|
|
// 如果当前的超时时间要大于缓存的,说明重新登录了,这个时候要把最新的放到缓存中
|
|
|
|
|
|
|
|
singleLoginTokenCacheMap.put(id, currentJwt);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// 走到这里,说明singleLoginTokenCache是最新的,说明当前请求的token就过期了
|
|
|
|
|
|
|
|
throw new BusinessException("当前用户已在其他地方登录!");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void cacheAuth(JWT jwt) {
|
|
|
|
private void cacheAuth(JWT jwt) {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
JSONObject claimsJson = jwt.getPayload().getClaimsJson();
|
|
|
|
JSONObject claimsJson = jwt.getPayload().getClaimsJson();
|
|
|
|