From 5a814b947cc28db5a7172928bef89c3067bb9fdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=B0=8F=E7=8E=8B=E5=AD=90?= Date: Tue, 27 Feb 2024 17:31:16 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E7=99=BB=E5=BD=95=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web}/listener/UserActionListener.java | 71 +++++++++++-------- .../ruoyi/web/service/SysLoginService.java | 6 ++ .../web/service/impl/EmailAuthStrategy.java | 4 -- .../service/impl/PasswordAuthStrategy.java | 5 -- .../web/service/impl/SocialAuthStrategy.java | 5 -- .../web/service/impl/XcxAuthStrategy.java | 1 - .../core/core/domain/dto/UserOnlineDTO.java | 10 +++ .../common/security/utils/LoginHelper.java | 49 +++++-------- 8 files changed, 78 insertions(+), 73 deletions(-) rename {ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security => ruoyi-admin/src/main/java/com/ruoyi/web}/listener/UserActionListener.java (62%) diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/listener/UserActionListener.java b/ruoyi-admin/src/main/java/com/ruoyi/web/listener/UserActionListener.java similarity index 62% rename from ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/listener/UserActionListener.java rename to ruoyi-admin/src/main/java/com/ruoyi/web/listener/UserActionListener.java index 2614890..ff4ae3f 100644 --- a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/listener/UserActionListener.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/listener/UserActionListener.java @@ -1,26 +1,30 @@ -package com.ruoyi.common.security.listener; +package com.ruoyi.web.listener; import cn.dev33.satoken.config.SaTokenConfig; import cn.dev33.satoken.listener.SaTokenListener; import cn.dev33.satoken.stp.SaLoginModel; import cn.hutool.http.useragent.UserAgent; import cn.hutool.http.useragent.UserAgentUtil; -import com.ruoyi.common.core.constant.CacheConstants; -import com.ruoyi.common.core.core.domain.dto.UserOnlineDTO; -import com.ruoyi.common.core.core.domain.model.LoginUser; -import com.ruoyi.common.core.enums.UserType; -import com.ruoyi.common.redis.utils.RedisUtils; -import com.ruoyi.common.security.utils.LoginHelper; -import com.ruoyi.common.core.utils.ip.AddressUtils; -import com.ruoyi.common.core.utils.ServletUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import com.ruoyi.common.core.constant.CacheConstants; +import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.common.core.core.domain.dto.UserOnlineDTO; +import com.ruoyi.common.core.utils.MessageUtils; +import com.ruoyi.common.core.utils.ServletUtils; +import com.ruoyi.common.core.utils.SpringUtils; +import com.ruoyi.common.core.utils.ip.AddressUtils; +import com.ruoyi.common.log.event.LogininforEvent; +import com.ruoyi.common.redis.utils.RedisUtils; +import com.ruoyi.common.security.utils.LoginHelper; +import com.ruoyi.common.tenant.helper.TenantHelper; +import com.ruoyi.web.service.SysLoginService; import org.springframework.stereotype.Component; import java.time.Duration; /** - * 用户行为 自定义侦听器 + * 用户行为 侦听器的实现 * * @author Lion Li */ @@ -30,35 +34,46 @@ import java.time.Duration; public class UserActionListener implements SaTokenListener { private final SaTokenConfig tokenConfig; + private final SysLoginService loginService; /** * 每次登录时触发 */ @Override public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) { - UserType userType = UserType.getUserType(loginId.toString()); - if (userType == UserType.SYS_USER) { - UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent")); - String ip = ServletUtils.getClientIP(); - LoginUser user = LoginHelper.getLoginUser(); - UserOnlineDTO dto = new UserOnlineDTO(); - dto.setIpaddr(ip); - dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); - dto.setBrowser(userAgent.getBrowser().getName()); - dto.setOs(userAgent.getOs().getName()); - dto.setLoginTime(System.currentTimeMillis()); - dto.setTokenId(tokenValue); - dto.setUserName(user.getUsername()); - dto.setDeptName(user.getDeptName()); + UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent")); + String ip = ServletUtils.getClientIP(); + UserOnlineDTO dto = new UserOnlineDTO(); + dto.setIpaddr(ip); + dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); + dto.setBrowser(userAgent.getBrowser().getName()); + dto.setOs(userAgent.getOs().getName()); + dto.setLoginTime(System.currentTimeMillis()); + dto.setTokenId(tokenValue); + String username = (String) loginModel.getExtra(LoginHelper.USER_NAME_KEY); + Long tenantId = (Long) loginModel.getExtra(LoginHelper.TENANT_KEY); + dto.setUserName(username); + dto.setClientKey((String) loginModel.getExtra(LoginHelper.CLIENT_KEY)); + dto.setDeviceType(loginModel.getDevice()); + dto.setDeptName((String) loginModel.getExtra(LoginHelper.DEPT_NAME_KEY)); + TenantHelper.dynamic(tenantId, () -> { if(tokenConfig.getTimeout() == -1) { RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto); } else { RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(tokenConfig.getTimeout())); } - log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue); - } else if (userType == UserType.APP_USER) { - // app端 自行根据业务编写 - } + }); + // 记录登录日志 + LogininforEvent logininforEvent = new LogininforEvent(); + logininforEvent.setTenantId(tenantId); + logininforEvent.setUsername(username); + logininforEvent.setStatus(Constants.LOGIN_SUCCESS); + logininforEvent.setMessage(MessageUtils.message("user.login.success")); + logininforEvent.setRequest(ServletUtils.getRequest()); + SpringUtils.context().publishEvent(logininforEvent); + // 更新登录信息 + loginService.recordLoginInfo((Long) loginModel.getExtra(LoginHelper.USER_KEY), ip); + log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue); } /** diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysLoginService.java b/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysLoginService.java index e76230e..57e9c48 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysLoginService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysLoginService.java @@ -244,11 +244,17 @@ public class SysLoginService { * @param userId 用户ID */ public void recordLoginInfo(Long userId, String ip) { + SysUserVo sysUserVo = userService.selectUserById(userId); + if (ObjectUtil.isNull(sysUserVo)) { + return; + } + SysUser sysUser = new SysUser(); sysUser.setUserId(userId); sysUser.setLoginIp(ip); sysUser.setLoginDate(DateUtils.getNowDate()); sysUser.setUpdateBy(userId); + sysUser.setVersion(sysUserVo.getVersion()); userService.updateById(sysUser); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/EmailAuthStrategy.java b/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/EmailAuthStrategy.java index 41ec96c..cc28428 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/EmailAuthStrategy.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/EmailAuthStrategy.java @@ -5,7 +5,6 @@ import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.util.ObjectUtil; import com.ruoyi.common.core.core.domain.model.EmailLoginBody; import com.ruoyi.common.json.utils.JsonUtils; -import com.ruoyi.common.tenant.helper.TenantHelper; import com.ruoyi.system.domain.vo.SysClientVo; import com.ruoyi.system.domain.vo.SysUserVo; import com.ruoyi.system.service.ISysUserService; @@ -70,9 +69,6 @@ public class EmailAuthStrategy implements IAuthStrategy { // 生成token LoginHelper.login(loginUser, model); -// loginService.recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); -// loginService.recordLoginInfo(user.getUserId()); - LoginVo loginVo = new LoginVo(); loginVo.setAccessToken(StpUtil.getTokenValue()); loginVo.setExpireIn(StpUtil.getTokenTimeout()); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/PasswordAuthStrategy.java b/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/PasswordAuthStrategy.java index e44f0e0..d69de7e 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/PasswordAuthStrategy.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/PasswordAuthStrategy.java @@ -6,7 +6,6 @@ import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.util.ObjectUtil; import com.ruoyi.common.core.core.domain.model.PasswordLoginBody; import com.ruoyi.common.json.utils.JsonUtils; -import com.ruoyi.common.tenant.helper.TenantHelper; import com.ruoyi.system.domain.vo.SysClientVo; import com.ruoyi.system.service.ISysUserService; import jakarta.annotation.Resource; @@ -26,7 +25,6 @@ import com.ruoyi.common.core.utils.ValidatorUtils; import com.ruoyi.common.redis.utils.RedisUtils; import com.ruoyi.common.security.utils.LoginHelper; import com.ruoyi.common.web.config.properties.CaptchaProperties; -import com.ruoyi.system.domain.SysClient; import com.ruoyi.system.domain.vo.SysUserVo; import com.ruoyi.web.domain.vo.LoginVo; import com.ruoyi.web.service.IAuthStrategy; @@ -81,9 +79,6 @@ public class PasswordAuthStrategy implements IAuthStrategy { // 生成token LoginHelper.login(loginUser, model); -// loginService.recordLogininfor(loginUser.getTenantId(), username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); -// loginService.recordLoginInfo(user.getUserId(),user.getVersion()); - LoginVo loginVo = new LoginVo(); loginVo.setAccessToken(StpUtil.getTokenValue()); loginVo.setExpireIn(StpUtil.getTokenTimeout()); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/SocialAuthStrategy.java b/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/SocialAuthStrategy.java index d1c0075..258fbde 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/SocialAuthStrategy.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/SocialAuthStrategy.java @@ -3,10 +3,7 @@ package com.ruoyi.web.service.impl; import cn.dev33.satoken.stp.SaLoginModel; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjectUtil; -import cn.hutool.http.HttpUtil; -import cn.hutool.http.Method; import com.ruoyi.system.service.ISysUserService; import jakarta.annotation.Resource; import lombok.RequiredArgsConstructor; @@ -23,11 +20,9 @@ import com.ruoyi.common.json.utils.JsonUtils; import com.ruoyi.common.security.utils.LoginHelper; import com.ruoyi.common.social.config.properties.SocialProperties; import com.ruoyi.common.social.utils.SocialUtils; -import com.ruoyi.common.tenant.helper.TenantHelper; import com.ruoyi.system.domain.vo.SysClientVo; import com.ruoyi.system.domain.vo.SysSocialVo; import com.ruoyi.system.domain.vo.SysUserVo; -import com.ruoyi.system.mapper.SysUserMapper; import com.ruoyi.system.service.ISysSocialService; import com.ruoyi.web.domain.vo.LoginVo; import com.ruoyi.web.service.IAuthStrategy; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/XcxAuthStrategy.java b/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/XcxAuthStrategy.java index cd702bb..38b5306 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/XcxAuthStrategy.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/service/impl/XcxAuthStrategy.java @@ -12,7 +12,6 @@ import com.ruoyi.common.core.enums.UserStatus; import com.ruoyi.common.core.utils.ValidatorUtils; import com.ruoyi.common.json.utils.JsonUtils; import com.ruoyi.common.security.utils.LoginHelper; -import com.ruoyi.system.domain.SysClient; import com.ruoyi.system.domain.vo.SysClientVo; import com.ruoyi.system.domain.vo.SysUserVo; import com.ruoyi.web.domain.vo.LoginVo; diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/core/domain/dto/UserOnlineDTO.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/core/domain/dto/UserOnlineDTO.java index 542f6ec..e19ddec 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/core/domain/dto/UserOnlineDTO.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/core/domain/dto/UserOnlineDTO.java @@ -34,6 +34,16 @@ public class UserOnlineDTO implements Serializable { */ private String userName; + /** + * 客户端 + */ + private String clientKey; + + /** + * 设备类型 + */ + private String deviceType; + /** * 登录IP地址 */ diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/utils/LoginHelper.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/utils/LoginHelper.java index 429a71e..9964d1a 100644 --- a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/utils/LoginHelper.java +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/utils/LoginHelper.java @@ -15,7 +15,6 @@ import com.ruoyi.common.core.core.domain.model.LoginUser; import com.ruoyi.common.core.enums.UserType; import java.util.Set; -import java.util.function.Supplier; /** * 登录鉴权助手 @@ -35,9 +34,10 @@ public class LoginHelper { public static final String LOGIN_USER_KEY = "loginUser"; public static final String TENANT_KEY = "tenantId"; public static final String USER_KEY = "userId"; + public static final String USER_NAME_KEY = "userName"; public static final String DEPT_KEY = "deptId"; + public static final String DEPT_NAME_KEY = "deptName"; public static final String CLIENT_KEY = "clientid"; - public static final String TENANT_ADMIN_KEY = "isTenantAdmin"; /** * 登录系统 基于 设备类型 @@ -57,7 +57,11 @@ public class LoginHelper { StpUtil.login(loginUser.getLoginId(), model.setExtra(TENANT_KEY, loginUser.getTenantId()) .setExtra(USER_KEY, loginUser.getUserId()) - .setExtra(DEPT_KEY, loginUser.getDeptId())); + .setExtra(DEPT_KEY, loginUser.getDeptId()) + .setExtra(TENANT_KEY, loginUser.getTenantId()) + .setExtra(DEPT_NAME_KEY, loginUser.getDeptName()) + .setExtra(USER_NAME_KEY, loginUser.getUsername()) + ); SaSession tokenSession = StpUtil.getTokenSession(); tokenSession.updateTimeout(model.getTimeout()); tokenSession.set(LOGIN_USER_KEY, loginUser); @@ -67,13 +71,11 @@ public class LoginHelper { * 获取用户(多级缓存) */ public static LoginUser getLoginUser() { - return (LoginUser) getStorageIfAbsentSet(LOGIN_USER_KEY, () -> { - SaSession session = StpUtil.getTokenSession(); - if (ObjectUtil.isNull(session)) { - return null; - } - return session.get(LOGIN_USER_KEY); - }); + SaSession session = StpUtil.getTokenSession(); + if (ObjectUtil.isNull(session)) { + return null; + } + return (LoginUser) session.get(LOGIN_USER_KEY); } /** @@ -91,7 +93,7 @@ public class LoginHelper { * 获取用户id */ public static Long getUserId() { - return Convert.toLong(getExtra(USER_KEY)); + return Convert.toLong(getExtra(USER_KEY)); } /** @@ -109,7 +111,11 @@ public class LoginHelper { } private static Object getExtra(String key) { - return getStorageIfAbsentSet(key, () -> StpUtil.getExtra(key)); + try { + return StpUtil.getExtra(key); + } catch (Exception e) { + return null; + } } /** @@ -152,27 +158,10 @@ public class LoginHelper { } public static boolean isTenantAdmin() { - Object value = getStorageIfAbsentSet(TENANT_ADMIN_KEY, () -> { - return isTenantAdmin(getLoginUser().getRolePermission()); - }); - return Convert.toBool(value); + return Convert.toBool(isTenantAdmin(getLoginUser().getRolePermission())); } public static boolean isLogin() { return getLoginUser() != null; } - - public static Object getStorageIfAbsentSet(String key, Supplier handle) { - try { - Object obj = SaHolder.getStorage().get(key); - if (ObjectUtil.isNull(obj)) { - obj = handle.get(); - SaHolder.getStorage().set(key, obj); - } - return obj; - } catch (Exception e) { - return null; - } - } - }