Browse Source

去除 LoginUser 的 updateTime、username、password、status 字段,简化

YunaiV 2 năm trước cách đây
mục cha
commit
73bf0b6f4f

+ 0 - 5
yudao-dependencies/pom.xml

@@ -172,11 +172,6 @@
                 <version>${revision}</version>
             </dependency>
 
-            <dependency>
-                <groupId>mysql</groupId>
-                <artifactId>mysql-connector-java</artifactId>
-                <version>${mysql.version}</version>
-            </dependency>
             <dependency>
                 <groupId>com.alibaba</groupId>
                 <artifactId>druid-spring-boot-starter</artifactId>

+ 3 - 65
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/LoginUser.java

@@ -1,14 +1,12 @@
 package cn.iocoder.yudao.framework.security.core;
 
 import cn.hutool.core.map.MapUtil;
-import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import lombok.Data;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
 
-import java.util.*;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * 登录用户信息
@@ -16,7 +14,7 @@ import java.util.*;
  * @author 芋道源码
  */
 @Data
-public class LoginUser implements UserDetails {
+public class LoginUser {
 
     /**
      * 用户编号
@@ -28,23 +26,6 @@ public class LoginUser implements UserDetails {
      * 关联 {@link UserTypeEnum}
      */
     private Integer userType;
-    /**
-     * 最后更新时间
-     */
-    private Date updateTime;
-
-    /**
-     * 用户名
-     */
-    private String username;
-    /**
-     * 密码
-     */
-    private String password;
-    /**
-     * 状态
-     */
-    private Integer status;
     /**
      * 租户编号
      */
@@ -59,49 +40,6 @@ public class LoginUser implements UserDetails {
     @JsonIgnore
     private Map<String, Object> context;
 
-    @Override
-    @JsonIgnore// 避免序列化
-    public String getPassword() {
-        return password;
-    }
-
-    @Override
-    public String getUsername() {
-        return username;
-    }
-
-    @Override
-    @JsonIgnore// 避免序列化
-    public boolean isEnabled() {
-        return CommonStatusEnum.ENABLE.getStatus().equals(status);
-    }
-
-    @Override
-    @JsonIgnore// 避免序列化
-    public Collection<? extends GrantedAuthority> getAuthorities() {
-        return new HashSet<>();
-    }
-
-    @Override
-    @JsonIgnore// 避免序列化
-    public boolean isAccountNonExpired() {
-        return true; // 返回 true,不依赖 Spring Security 判断
-    }
-
-    @Override
-    @JsonIgnore// 避免序列化
-    public boolean isAccountNonLocked() {
-        return true; // 返回 true,不依赖 Spring Security 判断
-    }
-
-    @Override
-    @JsonIgnore// 避免序列化
-    public boolean isCredentialsNonExpired() {
-        return true;  // 返回 true,不依赖 Spring Security 判断
-    }
-
-    // ========== 上下文 ==========
-
     public void setContext(String key, Object value) {
         if (context == null) {
             context = new HashMap<>();

+ 78 - 0
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/authentication/SpringSecurityUser.java

@@ -0,0 +1,78 @@
+package cn.iocoder.yudao.framework.security.core.authentication;
+
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * 登录用户信息
+ *
+ * @author 芋道源码
+ */
+@Data
+@AllArgsConstructor
+public class SpringSecurityUser implements UserDetails {
+
+    /**
+     * 用户编号
+     */
+    private Long id;
+
+    /**
+     * 用户名
+     */
+    private String username;
+    /**
+     * 密码
+     */
+    private String password;
+    /**
+     * 状态
+     */
+    private Integer status;
+    /**
+     * 租户编号
+     */
+    private Long tenantId;
+
+    @Override
+    public String getPassword() {
+        return password;
+    }
+
+    @Override
+    public String getUsername() {
+        return username;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return CommonStatusEnum.ENABLE.getStatus().equals(status);
+    }
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public boolean isAccountNonExpired() {
+        return true; // 返回 true,不依赖 Spring Security 判断
+    }
+
+    @Override
+    public boolean isAccountNonLocked() {
+        return true; // 返回 true,不依赖 Spring Security 判断
+    }
+
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return true;  // 返回 true,不依赖 Spring Security 判断
+    }
+
+}

+ 2 - 1
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/util/SecurityFrameworkUtils.java

@@ -11,6 +11,7 @@ import org.springframework.security.web.authentication.WebAuthenticationDetailsS
 import org.springframework.util.StringUtils;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.Collections;
 
 /**
  * 安全服务工具类
@@ -98,7 +99,7 @@ public class SecurityFrameworkUtils {
     private static Authentication buildAuthentication(LoginUser loginUser, HttpServletRequest request) {
         // 创建 UsernamePasswordAuthenticationToken 对象
         UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
-                loginUser, null, loginUser.getAuthorities());
+                loginUser, null, Collections.emptyList());
         authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
         return authenticationToken;
     }

+ 5 - 6
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java

@@ -1,7 +1,7 @@
 package cn.iocoder.yudao.module.member.convert.auth;
 
-import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 import cn.iocoder.yudao.framework.security.core.LoginUser;
+import cn.iocoder.yudao.framework.security.core.authentication.SpringSecurityUser;
 import cn.iocoder.yudao.module.member.controller.app.auth.vo.*;
 import cn.iocoder.yudao.module.member.controller.app.social.vo.AppSocialUserUnbindReqVO;
 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
@@ -19,13 +19,12 @@ public interface AuthConvert {
 
     AuthConvert INSTANCE = Mappers.getMapper(AuthConvert.class);
 
+    LoginUser convert(MemberUserDO bean);
+
     @Mapping(source = "mobile", target = "username")
-    LoginUser convert0(MemberUserDO bean);
+    SpringSecurityUser convert2(MemberUserDO user);
 
-    default LoginUser convert(MemberUserDO bean) {
-        // 目的,为了设置 UserTypeEnum.MEMBER.getValue()
-        return convert0(bean).setUserType(UserTypeEnum.MEMBER.getValue());
-    }
+    LoginUser convert(SpringSecurityUser bean);
 
     SocialUserBindReqDTO convert(Long userId, Integer userType, AppAuthSocialBindLoginReqVO reqVO);
     SocialUserBindReqDTO convert(Long userId, Integer userType, AppAuthSocialQuickLoginReqVO reqVO);

+ 42 - 49
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java

@@ -1,7 +1,6 @@
 package cn.iocoder.yudao.module.member.service.auth;
 
 import cn.hutool.core.lang.Assert;
-import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
 import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
@@ -78,7 +77,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
             throw new UsernameNotFoundException(mobile);
         }
         // 创建 LoginUser 对象
-        return AuthConvert.INSTANCE.convert(user);
+        return AuthConvert.INSTANCE.convert2(user);
     }
 
     @Override
@@ -87,7 +86,8 @@ public class MemberAuthServiceImpl implements MemberAuthService {
         LoginUser loginUser = login0(reqVO.getMobile(), reqVO.getPassword());
 
         // 缓存登录用户到 Redis 中,返回 Token 令牌
-        return createUserSessionAfterLoginSuccess(loginUser, LoginLogTypeEnum.LOGIN_USERNAME, userIp, userAgent);
+        return createUserSessionAfterLoginSuccess(loginUser, reqVO.getMobile(),
+                LoginLogTypeEnum.LOGIN_USERNAME, userIp, userAgent);
     }
 
     @Override
@@ -101,10 +101,11 @@ public class MemberAuthServiceImpl implements MemberAuthService {
         Assert.notNull(user, "获取用户失败,结果为空");
 
         // 执行登陆
-        LoginUser loginUser = AuthConvert.INSTANCE.convert(user);
+        LoginUser loginUser = buildLoginUser(user);
 
         // 缓存登录用户到 Redis 中,返回 Token 令牌
-        return createUserSessionAfterLoginSuccess(loginUser, LoginLogTypeEnum.LOGIN_SMS, userIp, userAgent);
+        return createUserSessionAfterLoginSuccess(loginUser, reqVO.getMobile(),
+                LoginLogTypeEnum.LOGIN_SMS, userIp, userAgent);
     }
 
     @Override
@@ -123,10 +124,11 @@ public class MemberAuthServiceImpl implements MemberAuthService {
         }
 
         // 创建 LoginUser 对象
-        LoginUser loginUser = AuthConvert.INSTANCE.convert(user);
+        LoginUser loginUser = buildLoginUser(user);
 
         // 缓存登录用户到 Redis 中,返回 Token 令牌
-        return createUserSessionAfterLoginSuccess(loginUser, LoginLogTypeEnum.LOGIN_SOCIAL, userIp, userAgent);
+        return createUserSessionAfterLoginSuccess(loginUser, null,
+                LoginLogTypeEnum.LOGIN_SOCIAL, userIp, userAgent);
     }
 
     @Override
@@ -142,9 +144,10 @@ public class MemberAuthServiceImpl implements MemberAuthService {
         return token;
     }
 
-    private String createUserSessionAfterLoginSuccess(LoginUser loginUser, LoginLogTypeEnum logType, String userIp, String userAgent) {
+    private String createUserSessionAfterLoginSuccess(LoginUser loginUser, String mobile,
+                                                      LoginLogTypeEnum logType, String userIp, String userAgent) {
         // 插入登陆日志
-        createLoginLog(loginUser.getUsername(), logType, LoginResultEnum.SUCCESS);
+        createLoginLog(loginUser.getId(), mobile, logType, LoginResultEnum.SUCCESS);
         // 缓存登录用户到 Redis 中,返回 Token 令牌
         return userSessionApi.createUserSession(loginUser, userIp, userAgent);
     }
@@ -164,29 +167,32 @@ public class MemberAuthServiceImpl implements MemberAuthService {
             authentication = authenticationManager.authenticate(new MultiUsernamePasswordAuthenticationToken(
                     username, password, getUserType()));
         } catch (BadCredentialsException badCredentialsException) {
-            this.createLoginLog(username, logType, LoginResultEnum.BAD_CREDENTIALS);
+            this.createLoginLog(null, username, logType, LoginResultEnum.BAD_CREDENTIALS);
             throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
         } catch (DisabledException disabledException) {
-            this.createLoginLog(username, logType, LoginResultEnum.USER_DISABLED);
+            this.createLoginLog(null, username, logType, LoginResultEnum.USER_DISABLED);
             throw exception(AUTH_LOGIN_USER_DISABLED);
         } catch (AuthenticationException authenticationException) {
             log.error("[login0][username({}) 发生未知异常]", username, authenticationException);
-            this.createLoginLog(username, logType, LoginResultEnum.UNKNOWN_ERROR);
+            this.createLoginLog(null, username, logType, LoginResultEnum.UNKNOWN_ERROR);
             throw exception(AUTH_LOGIN_FAIL_UNKNOWN);
         }
         Assert.notNull(authentication.getPrincipal(), "Principal 不会为空");
         return (LoginUser) authentication.getPrincipal();
     }
 
-    private void createLoginLog(String mobile, LoginLogTypeEnum logType, LoginResultEnum loginResult) {
+    private void createLoginLog(Long userId, String mobile, LoginLogTypeEnum logType, LoginResultEnum loginResult) {
         // 获得用户
-        MemberUserDO user = userService.getUserByMobile(mobile);
+        if (userId == null) {
+            MemberUserDO user = userService.getUserByMobile(mobile);
+            userId = user != null ? user.getId() : null;
+        }
         // 插入登录日志
         LoginLogCreateReqDTO reqDTO = new LoginLogCreateReqDTO();
         reqDTO.setLogType(logType.getType());
         reqDTO.setTraceId(TracerUtils.getTraceId());
-        if (user != null) {
-            reqDTO.setUserId(user.getId());
+        if (userId != null) {
+            reqDTO.setUserId(userId);
         }
         reqDTO.setUserType(getUserType().getValue());
         reqDTO.setUsername(mobile);
@@ -195,39 +201,14 @@ public class MemberAuthServiceImpl implements MemberAuthService {
         reqDTO.setResult(loginResult.getResult());
         loginLogApi.createLoginLog(reqDTO);
         // 更新最后登录时间
-        if (user != null && Objects.equals(LoginResultEnum.SUCCESS.getResult(), loginResult.getResult())) {
-            userService.updateUserLogin(user.getId(), getClientIP());
+        if (userId != null && Objects.equals(LoginResultEnum.SUCCESS.getResult(), loginResult.getResult())) {
+            userService.updateUserLogin(userId, getClientIP());
         }
     }
 
     @Override
     public LoginUser verifyTokenAndRefresh(String token) {
-        // 获得 LoginUser
-        LoginUser loginUser = userSessionApi.getLoginUser(token);
-        if (loginUser == null) {
-            return null;
-        }
-        // 刷新 LoginUser 缓存
-        this.refreshLoginUserCache(token, loginUser);
-        return loginUser;
-    }
-
-    private void refreshLoginUserCache(String token, LoginUser loginUser) {
-        // 每 1/3 的 Session 超时时间,刷新 LoginUser 缓存
-        if (System.currentTimeMillis() - loginUser.getUpdateTime().getTime() <
-                userSessionApi.getSessionTimeoutMillis() / 3) {
-            return;
-        }
-
-        // 重新加载 UserDO 信息
-        MemberUserDO user = userService.getUser(loginUser.getId());
-        if (user == null || CommonStatusEnum.DISABLE.getStatus().equals(user.getStatus())) {
-            // 校验 token 时,用户被禁用的情况下,也认为 token 过期,方便前端跳转到登录界面
-            throw exception(AUTH_TOKEN_EXPIRED);
-        }
-
-        // 刷新 LoginUser 缓存
-        userSessionApi.refreshUserSession(token, loginUser);
+        return userSessionApi.getLoginUser(token);
     }
 
     @Override
@@ -239,10 +220,10 @@ public class MemberAuthServiceImpl implements MemberAuthService {
         }
 
         // 执行登陆
-        this.createLoginLog(user.getMobile(), LoginLogTypeEnum.LOGIN_MOCK, LoginResultEnum.SUCCESS);
+        createLoginLog(userId, user.getMobile(), LoginLogTypeEnum.LOGIN_MOCK, LoginResultEnum.SUCCESS);
 
         // 创建 LoginUser 对象
-        return AuthConvert.INSTANCE.convert(user);
+        return buildLoginUser(user);
     }
 
     @Override
@@ -255,7 +236,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
         // 删除 session
         userSessionApi.deleteUserSession(token);
         // 记录登出日志
-        this.createLogoutLog(loginUser.getId(), loginUser.getUsername());
+        createLogoutLog(loginUser.getId());
     }
 
     @Override
@@ -321,17 +302,29 @@ public class MemberAuthServiceImpl implements MemberAuthService {
         return user;
     }
 
-    private void createLogoutLog(Long userId, String username) {
+    private void createLogoutLog(Long userId) {
         LoginLogCreateReqDTO reqDTO = new LoginLogCreateReqDTO();
         reqDTO.setLogType(LoginLogTypeEnum.LOGOUT_SELF.getType());
         reqDTO.setTraceId(TracerUtils.getTraceId());
         reqDTO.setUserId(userId);
         reqDTO.setUserType(getUserType().getValue());
-        reqDTO.setUsername(username);
+        reqDTO.setUsername(getMobile(userId));
         reqDTO.setUserAgent(ServletUtils.getUserAgent());
         reqDTO.setUserIp(getClientIP());
         reqDTO.setResult(LoginResultEnum.SUCCESS.getResult());
         loginLogApi.createLoginLog(reqDTO);
     }
 
+    private LoginUser buildLoginUser(MemberUserDO user) {
+        return AuthConvert.INSTANCE.convert(user).setUserType(getUserType().getValue());
+    }
+
+    private String getMobile(Long userId) {
+        if (userId == null) {
+            return null;
+        }
+        MemberUserDO user = userService.getUser(userId);
+        return user != null ? user.getMobile() : null;
+    }
+
 }

+ 5 - 10
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/auth/AuthConvert.java

@@ -1,20 +1,17 @@
 package cn.iocoder.yudao.module.system.convert.auth;
 
-import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.security.core.LoginUser;
-import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
+import cn.iocoder.yudao.framework.security.core.authentication.SpringSecurityUser;
 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
-import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO;
 import cn.iocoder.yudao.module.system.controller.admin.auth.vo.auth.*;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
 import cn.iocoder.yudao.module.system.enums.permission.MenuIdEnum;
 import org.mapstruct.Mapper;
-import org.mapstruct.Mapping;
 import org.mapstruct.factory.Mappers;
 import org.slf4j.LoggerFactory;
 
@@ -25,13 +22,11 @@ public interface AuthConvert {
 
     AuthConvert INSTANCE = Mappers.getMapper(AuthConvert.class);
 
-    @Mapping(source = "updateTime", target = "updateTime", ignore = true) // 字段相同,但是含义不同,忽略
-    LoginUser convert0(AdminUserDO bean);
+    LoginUser convert(AdminUserDO bean);
 
-    default LoginUser convert(AdminUserDO bean) {
-        // 目的,为了设置 UserTypeEnum.ADMIN.getValue()
-        return convert0(bean).setUserType(UserTypeEnum.ADMIN.getValue());
-    }
+    SpringSecurityUser convert2(AdminUserDO user);
+
+    LoginUser convert(SpringSecurityUser bean);
 
     default AuthPermissionInfoRespVO convert(AdminUserDO user, List<RoleDO> roleList, List<MenuDO> menuList) {
         return AuthPermissionInfoRespVO.builder()

+ 44 - 50
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java

@@ -1,12 +1,12 @@
 package cn.iocoder.yudao.module.system.service.auth;
 
-import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
 import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
 import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
 import cn.iocoder.yudao.framework.security.core.LoginUser;
 import cn.iocoder.yudao.framework.security.core.authentication.MultiUsernamePasswordAuthenticationToken;
+import cn.iocoder.yudao.framework.security.core.authentication.SpringSecurityUser;
 import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO;
 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
 import cn.iocoder.yudao.module.system.controller.admin.auth.vo.auth.*;
@@ -79,7 +79,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
             throw new UsernameNotFoundException(username);
         }
         // 创建 LoginUser 对象
-        return buildLoginUser(user);
+        return AuthConvert.INSTANCE.convert2(user);
     }
 
     @Override
@@ -89,7 +89,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
         if (user == null) {
             throw new UsernameNotFoundException(String.valueOf(userId));
         }
-        createLoginLog(user.getUsername(), LoginLogTypeEnum.LOGIN_MOCK, LoginResultEnum.SUCCESS);
+        createLoginLog(userId, user.getUsername(), LoginLogTypeEnum.LOGIN_MOCK, LoginResultEnum.SUCCESS);
 
         // 创建 LoginUser 对象
         return buildLoginUser(user);
@@ -104,7 +104,8 @@ public class AdminAuthServiceImpl implements AdminAuthService {
         LoginUser loginUser = login0(reqVO.getUsername(), reqVO.getPassword());
 
         // 缓存登陆用户到 Redis 中,返回 Token 令牌
-        return createUserSessionAfterLoginSuccess(loginUser, LoginLogTypeEnum.LOGIN_USERNAME, userIp, userAgent);
+        return createUserSessionAfterLoginSuccess(loginUser, reqVO.getUsername(),
+                LoginLogTypeEnum.LOGIN_USERNAME, userIp, userAgent);
     }
 
     @Override
@@ -132,7 +133,8 @@ public class AdminAuthServiceImpl implements AdminAuthService {
         LoginUser loginUser = buildLoginUser(user);
 
         // 缓存登陆用户到 Redis 中,返回 sessionId 编号
-        return createUserSessionAfterLoginSuccess(loginUser, LoginLogTypeEnum.LOGIN_MOBILE, userIp, userAgent);
+        return createUserSessionAfterLoginSuccess(loginUser, reqVO.getMobile(),
+                LoginLogTypeEnum.LOGIN_MOBILE, userIp, userAgent);
     }
 
     private void verifyCaptcha(AuthLoginReqVO reqVO) {
@@ -147,13 +149,13 @@ public class AdminAuthServiceImpl implements AdminAuthService {
         String code = captchaService.getCaptchaCode(reqVO.getUuid());
         if (code == null) {
             // 创建登录失败日志(验证码不存在)
-            this.createLoginLog(reqVO.getUsername(), logTypeEnum, LoginResultEnum.CAPTCHA_NOT_FOUND);
+            createLoginLog(null, reqVO.getUsername(), logTypeEnum, LoginResultEnum.CAPTCHA_NOT_FOUND);
             throw exception(AUTH_LOGIN_CAPTCHA_NOT_FOUND);
         }
         // 验证码不正确
         if (!code.equals(reqVO.getCode())) {
             // 创建登录失败日志(验证码不正确)
-            this.createLoginLog(reqVO.getUsername(), logTypeEnum, LoginResultEnum.CAPTCHA_CODE_ERROR);
+            createLoginLog(null, reqVO.getUsername(), logTypeEnum, LoginResultEnum.CAPTCHA_CODE_ERROR);
             throw exception(AUTH_LOGIN_CAPTCHA_CODE_ERROR);
         }
         // 正确,所以要删除下验证码
@@ -170,29 +172,35 @@ public class AdminAuthServiceImpl implements AdminAuthService {
             authentication = authenticationManager.authenticate(new MultiUsernamePasswordAuthenticationToken(
                     username, password, getUserType()));
         } catch (BadCredentialsException badCredentialsException) {
-            this.createLoginLog(username, logTypeEnum, LoginResultEnum.BAD_CREDENTIALS);
+            createLoginLog(null, username, logTypeEnum, LoginResultEnum.BAD_CREDENTIALS);
             throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
         } catch (DisabledException disabledException) {
-            this.createLoginLog(username, logTypeEnum, LoginResultEnum.USER_DISABLED);
+            createLoginLog(null, username, logTypeEnum, LoginResultEnum.USER_DISABLED);
             throw exception(AUTH_LOGIN_USER_DISABLED);
         } catch (AuthenticationException authenticationException) {
             log.error("[login0][username({}) 发生未知异常]", username, authenticationException);
-            this.createLoginLog(username, logTypeEnum, LoginResultEnum.UNKNOWN_ERROR);
+            createLoginLog(null, username, logTypeEnum, LoginResultEnum.UNKNOWN_ERROR);
             throw exception(AUTH_LOGIN_FAIL_UNKNOWN);
         }
         Assert.notNull(authentication.getPrincipal(), "Principal 不会为空");
-        return (LoginUser) authentication.getPrincipal();
+        // 构建 User 对象
+        return AuthConvert.INSTANCE.convert((SpringSecurityUser) authentication.getPrincipal())
+                .setUserType(getUserType().getValue());
     }
 
-    private void createLoginLog(String username, LoginLogTypeEnum logTypeEnum, LoginResultEnum loginResult) {
+    private void createLoginLog(Long userId, String username,
+                                LoginLogTypeEnum logTypeEnum, LoginResultEnum loginResult) {
         // 获得用户
-        AdminUserDO user = userService.getUserByUsername(username);
+        if (userId == null) {
+            AdminUserDO user = userService.getUserByUsername(username);
+            userId = user != null ? user.getId() : null;
+        }
         // 插入登录日志
         LoginLogCreateReqDTO reqDTO = new LoginLogCreateReqDTO();
         reqDTO.setLogType(logTypeEnum.getType());
         reqDTO.setTraceId(TracerUtils.getTraceId());
-        if (user != null) {
-            reqDTO.setUserId(user.getId());
+        if (userId != null) {
+            reqDTO.setUserId(userId);
         }
         reqDTO.setUserType(getUserType().getValue());
         reqDTO.setUsername(username);
@@ -201,8 +209,8 @@ public class AdminAuthServiceImpl implements AdminAuthService {
         reqDTO.setResult(loginResult.getResult());
         loginLogService.createLoginLog(reqDTO);
         // 更新最后登录时间
-        if (user != null && Objects.equals(LoginResultEnum.SUCCESS.getResult(), loginResult.getResult())) {
-            userService.updateUserLogin(user.getId(), ServletUtils.getClientIP());
+        if (userId != null && Objects.equals(LoginResultEnum.SUCCESS.getResult(), loginResult.getResult())) {
+            userService.updateUserLogin(userId, ServletUtils.getClientIP());
         }
     }
 
@@ -225,7 +233,8 @@ public class AdminAuthServiceImpl implements AdminAuthService {
         LoginUser loginUser = buildLoginUser(user);
 
         // 缓存登录用户到 Redis 中,返回 Token 令牌
-        return createUserSessionAfterLoginSuccess(loginUser, LoginLogTypeEnum.LOGIN_SOCIAL, userIp, userAgent);
+        return createUserSessionAfterLoginSuccess(loginUser, null,
+                LoginLogTypeEnum.LOGIN_SOCIAL, userIp, userAgent);
     }
 
     @Override
@@ -237,12 +246,14 @@ public class AdminAuthServiceImpl implements AdminAuthService {
         socialUserService.bindSocialUser(AuthConvert.INSTANCE.convert(loginUser.getId(), getUserType().getValue(), reqVO));
 
         // 缓存登录用户到 Redis 中,返回 Token 令牌
-        return createUserSessionAfterLoginSuccess(loginUser, LoginLogTypeEnum.LOGIN_SOCIAL, userIp, userAgent);
+        return createUserSessionAfterLoginSuccess(loginUser, reqVO.getUsername(),
+                LoginLogTypeEnum.LOGIN_SOCIAL, userIp, userAgent);
     }
 
-    private String createUserSessionAfterLoginSuccess(LoginUser loginUser, LoginLogTypeEnum logType, String userIp, String userAgent) {
+    private String createUserSessionAfterLoginSuccess(LoginUser loginUser, String username,
+                                                      LoginLogTypeEnum logType, String userIp, String userAgent) {
         // 插入登陆日志
-        createLoginLog(loginUser.getUsername(), logType, LoginResultEnum.SUCCESS);
+        createLoginLog(loginUser.getId(), username, logType, LoginResultEnum.SUCCESS);
         // 缓存登录用户到 Redis 中,返回 Token 令牌
         return userSessionService.createUserSession(loginUser, userIp, userAgent);
     }
@@ -257,7 +268,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
         // 删除 session
         userSessionService.deleteUserSession(token);
         // 记录登出日志
-        createLogoutLog(loginUser.getId(), loginUser.getUsername());
+        createLogoutLog(loginUser.getId());
     }
 
     @Override
@@ -265,13 +276,13 @@ public class AdminAuthServiceImpl implements AdminAuthService {
         return UserTypeEnum.ADMIN;
     }
 
-    private void createLogoutLog(Long userId, String username) {
+    private void createLogoutLog(Long userId) {
         LoginLogCreateReqDTO reqDTO = new LoginLogCreateReqDTO();
         reqDTO.setLogType(LoginLogTypeEnum.LOGOUT_SELF.getType());
         reqDTO.setTraceId(TracerUtils.getTraceId());
         reqDTO.setUserId(userId);
+        reqDTO.setUsername(getUsername(userId));
         reqDTO.setUserType(getUserType().getValue());
-        reqDTO.setUsername(username);
         reqDTO.setUserAgent(ServletUtils.getUserAgent());
         reqDTO.setUserIp(ServletUtils.getClientIP());
         reqDTO.setResult(LoginResultEnum.SUCCESS.getResult());
@@ -280,36 +291,19 @@ public class AdminAuthServiceImpl implements AdminAuthService {
 
     @Override
     public LoginUser verifyTokenAndRefresh(String token) {
-        // 获得 LoginUser
-        LoginUser loginUser = userSessionService.getLoginUser(token);
-        if (loginUser == null) {
-            return null;
-        }
-        // 刷新 LoginUser 缓存
-        return this.refreshLoginUserCache(token, loginUser);
+        return userSessionService.getLoginUser(token);
     }
 
-    private LoginUser refreshLoginUserCache(String token, LoginUser loginUser) {
-        // 每 1/3 的 Session 超时时间,刷新 LoginUser 缓存
-        if (System.currentTimeMillis() - loginUser.getUpdateTime().getTime() <
-                userSessionService.getSessionTimeoutMillis() / 3) {
-            return loginUser;
-        }
-
-        // 重新加载 AdminUserDO 信息
-        AdminUserDO user = userService.getUser(loginUser.getId());
-        if (user == null || CommonStatusEnum.DISABLE.getStatus().equals(user.getStatus())) {
-            throw exception(AUTH_TOKEN_EXPIRED); // 校验 token 时,用户被禁用的情况下,也认为 token 过期,方便前端跳转到登录界面
-        }
-
-        // 刷新 LoginUser 缓存
-        LoginUser newLoginUser= buildLoginUser(user);
-        userSessionService.refreshUserSession(token, newLoginUser);
-        return newLoginUser;
+    private LoginUser buildLoginUser(AdminUserDO user) {
+        return AuthConvert.INSTANCE.convert(user).setUserType(getUserType().getValue());
     }
 
-    private LoginUser buildLoginUser(AdminUserDO user) {
-        return AuthConvert.INSTANCE.convert(user);
+    private String getUsername(Long userId) {
+        if (userId == null) {
+            return null;
+        }
+        AdminUserDO user = userService.getUser(userId);
+        return user != null ? user.getUsername() : null;
     }
 
 }

+ 2 - 12
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/UserSessionServiceImpl.java

@@ -23,7 +23,6 @@ import org.springframework.stereotype.Service;
 import javax.annotation.Resource;
 import java.time.Duration;
 import java.util.Collection;
-import java.util.Date;
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -106,12 +105,11 @@ public class UserSessionServiceImpl implements UserSessionService {
         // 生成 Session 编号
         String token = generateToken();
         // 写入 Redis 缓存
-        loginUser.setUpdateTime(new Date());
         loginUserRedisDAO.set(token, loginUser);
         // 写入 DB 中
         UserSessionDO userSession = UserSessionDO.builder().token(token)
                 .userId(loginUser.getId()).userType(loginUser.getUserType())
-                .userIp(userIp).userAgent(userAgent).username(loginUser.getUsername())
+                .userIp(userIp).userAgent(userAgent).username("")
                 .sessionTimeout(addTime(Duration.ofMillis(getSessionTimeoutMillis())))
                 .build();
         userSessionMapper.insert(userSession);
@@ -121,15 +119,7 @@ public class UserSessionServiceImpl implements UserSessionService {
 
     @Override
     public void refreshUserSession(String token, LoginUser loginUser) {
-        // 写入 Redis 缓存
-        loginUser.setUpdateTime(new Date());
-        loginUserRedisDAO.set(token, loginUser);
-        // 更新 DB 中
-        UserSessionDO updateObj = UserSessionDO.builder().build();
-        updateObj.setUsername(loginUser.getUsername());
-        updateObj.setUpdateTime(new Date());
-        updateObj.setSessionTimeout(addTime(Duration.ofMillis(getSessionTimeoutMillis())));
-        userSessionMapper.updateByToken(token, updateObj);
+
     }
 
     @Override

+ 1 - 1
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/UserSessionServiceImplTest.java

@@ -201,7 +201,7 @@ public class UserSessionServiceImplTest extends BaseDbAndRedisUnitTest {
         assertPojoEquals(redisLoginUser, loginUser, "username", "password");
         // 校验 UserSessionDO 记录
         UserSessionDO updateDO = userSessionMapper.selectOne(UserSessionDO::getToken, token);
-        assertEquals(updateDO.getUsername(), loginUser.getUsername());
+//        assertEquals(updateDO.getUsername(), loginUser.getUsername());
         assertNotNull(userSession.getUpdateTime());
         assertNotNull(userSession.getSessionTimeout());
     }