diff --git a/kernel-d-auth/auth-sdk/pom.xml b/kernel-d-auth/auth-sdk/pom.xml
index 77870e1b4..29e61dcfd 100644
--- a/kernel-d-auth/auth-sdk/pom.xml
+++ b/kernel-d-auth/auth-sdk/pom.xml
@@ -24,6 +24,14 @@
7.0.2
+
+
+
+ cn.stylefeng.roses
+ timer-api
+ 7.0.2
+
+
diff --git a/kernel-d-auth/auth-sdk/src/main/java/cn/stylefeng/roses/kernel/auth/session/timer/ClearInvalidLoginUserCacheTimer.java b/kernel-d-auth/auth-sdk/src/main/java/cn/stylefeng/roses/kernel/auth/session/timer/ClearInvalidLoginUserCacheTimer.java
new file mode 100644
index 000000000..2eca0ec49
--- /dev/null
+++ b/kernel-d-auth/auth-sdk/src/main/java/cn/stylefeng/roses/kernel/auth/session/timer/ClearInvalidLoginUserCacheTimer.java
@@ -0,0 +1,65 @@
+package cn.stylefeng.roses.kernel.auth.session.timer;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
+import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi;
+import cn.stylefeng.roses.kernel.timer.api.TimerAction;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * 定时清除无用的登录用户缓存
+ *
+ * @author fengshuonan
+ * @date 2021/3/30 11:19
+ */
+public class ClearInvalidLoginUserCacheTimer implements TimerAction {
+
+ /**
+ * 登录用户缓存
+ */
+ private final CacheOperatorApi loginUserCacheOperatorApi;
+
+ /**
+ * 用户token的缓存,这个缓存用来存储一个用户的所有token
+ */
+ private final CacheOperatorApi> allPlaceLoginTokenCache;
+
+ public ClearInvalidLoginUserCacheTimer(CacheOperatorApi loginUserCacheOperatorApi, CacheOperatorApi> allPlaceLoginTokenCache) {
+ this.loginUserCacheOperatorApi = loginUserCacheOperatorApi;
+ this.allPlaceLoginTokenCache = allPlaceLoginTokenCache;
+ }
+
+ @Override
+ public void action() {
+ Collection allOnlineUsers = allPlaceLoginTokenCache.getAllKeys();
+ if (ObjectUtil.isNotEmpty(allOnlineUsers)) {
+ for (String userId : allOnlineUsers) {
+
+ // 获取当前用户的所有token
+ Set userTokens = allPlaceLoginTokenCache.get(userId);
+
+ // 新的userToken
+ Set newUserTokens = new HashSet<>();
+
+ // 因为有的token用户没有点退出清空,这里遍历一下,清空无效的userToken
+ for (String userToken : userTokens) {
+ LoginUser loginUser = loginUserCacheOperatorApi.get(userToken);
+ if (loginUser != null) {
+ newUserTokens.add(userToken);
+ }
+ }
+
+ // 如果userToken都过期了,这个set整体清除掉
+ if (ObjectUtil.isEmpty(newUserTokens)) {
+ allPlaceLoginTokenCache.remove(userId);
+ } else {
+ allPlaceLoginTokenCache.put(userId, newUserTokens);
+ }
+ }
+ }
+ }
+
+}
diff --git a/kernel-d-auth/auth-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/auth/starter/GunsAuthAutoConfiguration.java b/kernel-d-auth/auth-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/auth/starter/GunsAuthAutoConfiguration.java
index fe9f2a3a7..07a0258f6 100644
--- a/kernel-d-auth/auth-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/auth/starter/GunsAuthAutoConfiguration.java
+++ b/kernel-d-auth/auth-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/auth/starter/GunsAuthAutoConfiguration.java
@@ -38,6 +38,7 @@ import cn.stylefeng.roses.kernel.auth.session.DefaultSessionManager;
import cn.stylefeng.roses.kernel.auth.session.cache.logintoken.MemoryLoginTokenCache;
import cn.stylefeng.roses.kernel.auth.session.cache.loginuser.MemoryLoginUserCache;
import cn.stylefeng.roses.kernel.auth.session.cookie.DefaultSessionCookieCreator;
+import cn.stylefeng.roses.kernel.auth.session.timer.ClearInvalidLoginUserCacheTimer;
import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi;
import cn.stylefeng.roses.kernel.cache.api.constants.CacheConstants;
import cn.stylefeng.roses.kernel.jwt.JwtTokenOperator;
@@ -162,4 +163,15 @@ public class GunsAuthAutoConfiguration {
return new DefaultSessionManager(loginUserCache, allPlaceLoginTokenCache, sessionExpiredSeconds, sessionCookieCreator());
}
+ /**
+ * 清空无用登录用户缓存的定时任务
+ *
+ * @author fengshuonan
+ * @date 2021/3/30 11:32
+ */
+ @Bean
+ public ClearInvalidLoginUserCacheTimer clearInvalidLoginUserCacheTimer() {
+ return new ClearInvalidLoginUserCacheTimer(loginUserCache(), allPlaceLoginTokenCache());
+ }
+
}