|
|
|
@ -16,28 +16,34 @@ import javax.servlet.http.HttpServletRequest;
|
|
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
|
|
|
|
|
|
@Slf4j
|
|
|
|
|
public class JwtInterceptor implements HandlerInterceptor {
|
|
|
|
|
|
|
|
|
|
private static final ConcurrentHashMap<Object, JWT> singleLoginTokenCacheMap = new ConcurrentHashMap<>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
|
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
|
|
|
|
//请求消息头获取用户ID
|
|
|
|
|
String token = request.getHeader("token");
|
|
|
|
|
if (StrUtil.isBlank(token) ) {
|
|
|
|
|
if (StrUtil.isBlank(token)) {
|
|
|
|
|
// 如果是swagger来的接口,说明这里是测试的,会伪造一个用户
|
|
|
|
|
if (StrUtil.isNotBlank(request.getHeader("Knife4j-Gateway-Code"))){
|
|
|
|
|
token = devActiveUser();
|
|
|
|
|
}else {
|
|
|
|
|
throw new BusinessException("当前用户未登录",HttpStatus.UNAUTHORIZED.value());
|
|
|
|
|
if (StrUtil.isNotBlank(request.getHeader("Knife4j-Gateway-Code"))) {
|
|
|
|
|
cacheAuth(JWTUtil.parseToken(devActiveUser()));
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
throw new BusinessException("当前用户未登录", HttpStatus.UNAUTHORIZED.value());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JWT jwt = JWTUtil.parseToken(token);
|
|
|
|
|
// 校验token是否过期,如果过期了,需要提示过期重新登录
|
|
|
|
|
checkTokenExpire(jwt);
|
|
|
|
|
// 校验是否重复登录
|
|
|
|
|
checkSingleLogin(jwt);
|
|
|
|
|
cacheAuth(jwt);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@ -56,7 +62,27 @@ public class JwtInterceptor implements HandlerInterceptor {
|
|
|
|
|
// 校验是否比当前时间大
|
|
|
|
|
long currentTimeMillis = System.currentTimeMillis();
|
|
|
|
|
if (currentTimeMillis > l) {
|
|
|
|
|
throw new BusinessException("用户登录已过期,请重新登录",HttpStatus.UNAUTHORIZED.value());
|
|
|
|
|
throw new BusinessException("用户登录已过期,请重新登录", HttpStatus.UNAUTHORIZED.value());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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("当前用户已在其他地方登录!");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -69,11 +95,11 @@ public class JwtInterceptor implements HandlerInterceptor {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String devActiveUser(){
|
|
|
|
|
private String devActiveUser() {
|
|
|
|
|
Map<String, Object> map = new HashMap<>();
|
|
|
|
|
map.put("id","1");
|
|
|
|
|
map.put("account","test");
|
|
|
|
|
map.put("name","测试账户");
|
|
|
|
|
map.put("id", "1");
|
|
|
|
|
map.put("account", "test");
|
|
|
|
|
map.put("name", "测试账户");
|
|
|
|
|
return TokenUtil.creatToken(JSONUtil.toJsonStr(map));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|