diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index bf479a4..eb462b3 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -103,6 +103,8 @@ spring: shutdown-timeout: 1000 # token配置 token: + # 是否允许账户多终端同时登录(true允许 false不允许) + soloLogin: false # 令牌自定义标识 header: Authorization # 令牌密钥 diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java index 8727151..4625f5e 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -174,4 +174,9 @@ public class Constants * CAS登录成功后的前台Cookie的Key */ public static final String WEB_TOKEN_KEY = "Admin-Token"; + + /** + * 登录用户编号 redis key + */ + public static final String LOGIN_USERID_KEY = "login_userid:"; } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java index 53e8f57..5c6a6ae 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java @@ -43,7 +43,7 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler { String userName = loginUser.getUsername(); // 删除用户缓存记录 - tokenService.delLoginUser(loginUser.getToken()); + tokenService.delLoginUser(loginUser.getToken(), loginUser.getUser().getUserId()); // 记录用户退出日志 AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, MessageUtils.message("user.logout.success"))); } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java index 84c86be..968b269 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java @@ -4,6 +4,7 @@ import javax.annotation.Resource; import com.ruoyi.common.exception.user.*; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -34,6 +35,10 @@ import com.ruoyi.system.service.ISysUserService; @Component public class SysLoginService { + // 是否允许账户多终端同时登录(true允许 false不允许) + @Value("${token.soloLogin}") + private boolean soloLogin; + @Autowired private TokenService tokenService; @@ -93,6 +98,20 @@ public class SysLoginService AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); LoginUser loginUser = (LoginUser) authentication.getPrincipal(); recordLoginInfo(loginUser.getUserId()); + + // 添加到这里 + // 判断是否允许账户多终端同时登录 + if (!soloLogin) + { + // 如果用户不允许多终端同时登录,清除缓存信息 + String userIdKey = Constants.LOGIN_USERID_KEY + loginUser.getUser().getUserId(); + String userKey = redisCache.getCacheObject(userIdKey); + if (StringUtils.isNotEmpty(userKey)) + { + redisCache.deleteObject(userIdKey); + redisCache.deleteObject(userKey); + } + } // 生成token return tokenService.createToken(loginUser); } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java index 02d39da..05dec5d 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java @@ -33,6 +33,10 @@ public class TokenService { private static final Logger log = LoggerFactory.getLogger(TokenService.class); + // 是否允许账户多终端同时登录(true允许 false不允许) + @Value("${token.soloLogin}") + private boolean soloLogin; + // 令牌自定义标识 @Value("${token.header}") private String header; @@ -128,13 +132,20 @@ public class TokenService /** * 删除用户身份信息 */ - public void delLoginUser(String token) + public void delLoginUser(String token, Long userId) { if (StringUtils.isNotEmpty(token)) { String userKey = getTokenKey(token); redisCache.deleteObject(userKey); } + + //在原有代码上添加下面的代码 + if (!soloLogin && StringUtils.isNotNull(userId)) + { + String userIdKey = getUserIdKey(userId); + redisCache.deleteObject(userIdKey); + } } /** @@ -183,6 +194,14 @@ public class TokenService // 根据uuid将loginUser缓存 String userKey = getTokenKey(loginUser.getToken()); redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); + + //在原有代码上添加下面的代码 + if (!soloLogin) + { + // 缓存用户唯一标识,防止同一帐号,同时登录 + String userIdKey = getUserIdKey(loginUser.getUser().getUserId()); + redisCache.setCacheObject(userIdKey, userKey, expireTime, TimeUnit.MINUTES); + } } /** @@ -265,4 +284,7 @@ public class TokenService { return CacheConstants.LOGIN_TOKEN_KEY + uuid; } + + //添加下面的代码 + private String getUserIdKey(Long userId){return Constants.LOGIN_USERID_KEY + userId;} }