diff --git a/virtual-patient-common/pom.xml b/virtual-patient-common/pom.xml
index f666a501..39517bdf 100644
--- a/virtual-patient-common/pom.xml
+++ b/virtual-patient-common/pom.xml
@@ -30,6 +30,15 @@
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+ redis.clients
+ jedis
+
+
org.springframework.boot
diff --git a/virtual-patient-common/src/main/java/com/supervision/config/JwtInterceptor.java b/virtual-patient-common/src/main/java/com/supervision/config/JwtInterceptor.java
index cd4374d1..8513504d 100644
--- a/virtual-patient-common/src/main/java/com/supervision/config/JwtInterceptor.java
+++ b/virtual-patient-common/src/main/java/com/supervision/config/JwtInterceptor.java
@@ -1,13 +1,17 @@
package com.supervision.config;
+import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
+import com.supervision.constant.UserTokenConstant;
import com.supervision.exception.BusinessException;
+import com.supervision.util.SpringBeanUtil;
import com.supervision.util.TokenUtil;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
@@ -19,10 +23,16 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
@Slf4j
public class JwtInterceptor implements HandlerInterceptor {
+ private final RedisTemplate redisTemplate;
+
+ public JwtInterceptor(RedisTemplate redisTemplate) {
+ this.redisTemplate = redisTemplate;
+ }
@Override
@@ -43,11 +53,33 @@ public class JwtInterceptor implements HandlerInterceptor {
// 校验token是否过期,如果过期了,需要提示过期重新登录
checkTokenExpire(jwt);
// 校验是否重复登录
- //UserSingleLoginConfig.checkSingleLogin(jwt);
+ //checkSingleLogin(jwt);
cacheAuth(jwt);
return true;
}
+ public void checkSingleLogin(String userId, JWT currentJwt) {
+
+ if (Boolean.FALSE.equals(redisTemplate.hasKey(UserTokenConstant.TOKEN_CACHE + userId))) {
+ throw new BusinessException("用户已被踢下线或超时,请重新登录", 505);
+ }
+ String value = redisTemplate.opsForValue().get(UserTokenConstant.TOKEN_CACHE + userId);
+
+ long redisCacheTime = Long.parseLong(String.valueOf(value));
+ Object currentJwtIssueTimeObject = currentJwt.getPayload("issueTime");
+ long currentJwtIssueTime = Long.parseLong(String.valueOf(currentJwtIssueTimeObject));
+ if (redisCacheTime == currentJwtIssueTime) {
+ // 如果相等,说明这个token就是最新的,直接放行
+ return;
+ } else if (currentJwtIssueTime > redisCacheTime) {
+ // 如果当前请求时间,大于Redis缓存时间,说明重新登录了,这个时候要把最新的放到缓存中
+ redisTemplate.opsForValue().set(UserTokenConstant.TOKEN_CACHE + userId, String.valueOf(System.currentTimeMillis()), 1000 * 5L, TimeUnit.MILLISECONDS);
+ } else {
+ // 走到这里,说明redisCacheTime是最新的,说明当前用户请求了一个新的token,那么原来的用户就踢掉
+ throw new BusinessException("当前用户已在其他地方登录!", 505);
+ }
+ }
+
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception {
@@ -68,7 +100,6 @@ public class JwtInterceptor implements HandlerInterceptor {
}
-
private void cacheAuth(JWT jwt) {
try {
JSONObject claimsJson = jwt.getPayload().getClaimsJson();
diff --git a/virtual-patient-common/src/main/java/com/supervision/config/UserSingleLoginConfig.java b/virtual-patient-common/src/main/java/com/supervision/config/UserSingleLoginConfig.java
deleted file mode 100644
index c3f0f837..00000000
--- a/virtual-patient-common/src/main/java/com/supervision/config/UserSingleLoginConfig.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.supervision.config;
-
-import cn.hutool.cache.CacheUtil;
-import cn.hutool.cache.impl.TimedCache;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.jwt.JWT;
-import com.supervision.exception.BusinessException;
-import lombok.extern.slf4j.Slf4j;
-
-@Slf4j
-public class UserSingleLoginConfig {
-
- /**
- * 创建缓存,过期时间为5分钟,如果5分钟内没有请求过来,就认为是超时
- */
- private static final TimedCache