mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-11-01 03:28:41 +08:00 
			
		
		
		
	1. 增加前台用户的 token 刷新
2. 增加前台用户的 logout 退出
This commit is contained in:
		| @ -16,10 +16,7 @@ public interface SysErrorCodeConstants { | |||||||
|     ErrorCode AUTH_LOGIN_CAPTCHA_NOT_FOUND = new ErrorCode(1002000003, "验证码不存在"); |     ErrorCode AUTH_LOGIN_CAPTCHA_NOT_FOUND = new ErrorCode(1002000003, "验证码不存在"); | ||||||
|     ErrorCode AUTH_LOGIN_CAPTCHA_CODE_ERROR = new ErrorCode(1002000004, "验证码不正确"); |     ErrorCode AUTH_LOGIN_CAPTCHA_CODE_ERROR = new ErrorCode(1002000004, "验证码不正确"); | ||||||
|     ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1002000005, "未绑定账号,需要进行绑定"); |     ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1002000005, "未绑定账号,需要进行绑定"); | ||||||
|  |     ErrorCode AUTH_TOKEN_EXPIRED = new ErrorCode(1002000006, "Token 已经过期"); | ||||||
|     // ========== TOKEN 模块 1002001000 ========== |  | ||||||
|     ErrorCode TOKEN_EXPIRED = new ErrorCode(1002001000, "Token 已经过期"); |  | ||||||
|     ErrorCode TOKEN_PARSE_FAIL = new ErrorCode(1002001001, "Token 解析失败"); |  | ||||||
|  |  | ||||||
|     // ========== 菜单模块 1002002000 ========== |     // ========== 菜单模块 1002002000 ========== | ||||||
|     ErrorCode MENU_NAME_DUPLICATE = new ErrorCode(1002002000, "已经存在该名字的菜单"); |     ErrorCode MENU_NAME_DUPLICATE = new ErrorCode(1002002000, "已经存在该名字的菜单"); | ||||||
|  | |||||||
| @ -255,15 +255,15 @@ public class SysAuthServiceImpl implements SysAuthService { | |||||||
|         } |         } | ||||||
|         // 删除 session |         // 删除 session | ||||||
|         userSessionCoreService.deleteUserSession(token); |         userSessionCoreService.deleteUserSession(token); | ||||||
|         // 记录登出日子和 |         // 记录登出日志 | ||||||
|         this.createLogoutLog(loginUser.getUsername()); |         this.createLogoutLog(loginUser.getId(), loginUser.getUsername()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void createLogoutLog(String username) { |     private void createLogoutLog(Long userId, String username) { | ||||||
|         // TODO 芋艿:这里未设置 userId |  | ||||||
|         SysLoginLogCreateReqDTO reqDTO = new SysLoginLogCreateReqDTO(); |         SysLoginLogCreateReqDTO reqDTO = new SysLoginLogCreateReqDTO(); | ||||||
|         reqDTO.setLogType(SysLoginLogTypeEnum.LOGOUT_SELF.getType()); |         reqDTO.setLogType(SysLoginLogTypeEnum.LOGOUT_SELF.getType()); | ||||||
|         reqDTO.setTraceId(TracerUtils.getTraceId()); |         reqDTO.setTraceId(TracerUtils.getTraceId()); | ||||||
|  |         reqDTO.setUserId(userId); | ||||||
|         reqDTO.setUserType(UserTypeEnum.ADMIN.getValue()); |         reqDTO.setUserType(UserTypeEnum.ADMIN.getValue()); | ||||||
|         reqDTO.setUsername(username); |         reqDTO.setUsername(username); | ||||||
|         reqDTO.setUserAgent(ServletUtils.getUserAgent()); |         reqDTO.setUserAgent(ServletUtils.getUserAgent()); | ||||||
| @ -294,7 +294,7 @@ public class SysAuthServiceImpl implements SysAuthService { | |||||||
|         // 重新加载 SysUserDO 信息 |         // 重新加载 SysUserDO 信息 | ||||||
|         SysUserDO user = userService.getUser(loginUser.getId()); |         SysUserDO user = userService.getUser(loginUser.getId()); | ||||||
|         if (user == null || CommonStatusEnum.DISABLE.getStatus().equals(user.getStatus())) { |         if (user == null || CommonStatusEnum.DISABLE.getStatus().equals(user.getStatus())) { | ||||||
|             throw exception(TOKEN_EXPIRED); // 校验 token 时,用户被禁用的情况下,也认为 token 过期,方便前端跳转到登录界面 |             throw exception(AUTH_TOKEN_EXPIRED); // 校验 token 时,用户被禁用的情况下,也认为 token 过期,方便前端跳转到登录界面 | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // 刷新 LoginUser 缓存 |         // 刷新 LoginUser 缓存 | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| package cn.iocoder.yudao.userserver.modules.member.service.user; | package cn.iocoder.yudao.userserver.modules.member.service.user; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.framework.common.validation.Mobile; | ||||||
| import cn.iocoder.yudao.userserver.modules.member.dal.dataobject.user.MbrUserDO; | import cn.iocoder.yudao.userserver.modules.member.dal.dataobject.user.MbrUserDO; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @ -17,6 +18,16 @@ public interface MbrUserService { | |||||||
|      */ |      */ | ||||||
|     MbrUserDO getUserByMobile(String mobile); |     MbrUserDO getUserByMobile(String mobile); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 基于手机号创建用户。 | ||||||
|  |      * 如果用户已经存在,则直接进行返回 | ||||||
|  |      * | ||||||
|  |      * @param mobile 手机号 | ||||||
|  |      * @param registerIp 注册 IP | ||||||
|  |      * @return 用户对象 | ||||||
|  |      */ | ||||||
|  |     MbrUserDO createUserIfAbsent(@Mobile String mobile, String registerIp); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 更新用户的最后登陆信息 |      * 更新用户的最后登陆信息 | ||||||
|      * |      * | ||||||
|  | |||||||
| @ -1,9 +1,14 @@ | |||||||
| package cn.iocoder.yudao.userserver.modules.member.service.user.impl; | package cn.iocoder.yudao.userserver.modules.member.service.user.impl; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.util.IdUtil; | ||||||
|  | import cn.hutool.core.util.RandomUtil; | ||||||
|  | import cn.hutool.core.util.StrUtil; | ||||||
|  | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||||||
| import cn.iocoder.yudao.userserver.modules.member.dal.dataobject.user.MbrUserDO; | import cn.iocoder.yudao.userserver.modules.member.dal.dataobject.user.MbrUserDO; | ||||||
| import cn.iocoder.yudao.userserver.modules.member.dal.mysql.user.MbrUserMapper; | import cn.iocoder.yudao.userserver.modules.member.dal.mysql.user.MbrUserMapper; | ||||||
| import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; | import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; | ||||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||||
|  | import org.springframework.security.crypto.password.PasswordEncoder; | ||||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||||
|  |  | ||||||
| import javax.annotation.Resource; | import javax.annotation.Resource; | ||||||
| @ -23,11 +28,38 @@ public class MbrUserServiceImpl implements MbrUserService { | |||||||
|     @Resource |     @Resource | ||||||
|     private MbrUserMapper userMapper; |     private MbrUserMapper userMapper; | ||||||
|  |  | ||||||
|  |     @Resource | ||||||
|  |     private PasswordEncoder passwordEncoder; | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public MbrUserDO getUserByMobile(String mobile) { |     public MbrUserDO getUserByMobile(String mobile) { | ||||||
|         return userMapper.selectByMobile(mobile); |         return userMapper.selectByMobile(mobile); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public MbrUserDO createUserIfAbsent(String mobile, String registerIp) { | ||||||
|  |         // 用户已经存在 | ||||||
|  |         MbrUserDO user = userMapper.selectByMobile(mobile); | ||||||
|  |         if (user != null) { | ||||||
|  |             return user; | ||||||
|  |         } | ||||||
|  |         // 用户不存在,则进行创建 | ||||||
|  |         return this.createUser(mobile, registerIp); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private MbrUserDO createUser(String mobile, String registerIp) { | ||||||
|  |         // 生成密码 | ||||||
|  |         String password = IdUtil.fastSimpleUUID(); | ||||||
|  |         // 插入用户 | ||||||
|  |         MbrUserDO user = new MbrUserDO(); | ||||||
|  |         user.setMobile(mobile); | ||||||
|  |         user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启 | ||||||
|  |         user.setPassword(passwordEncoder.encode(password)); // 加密密码 | ||||||
|  |         user.setRegisterIp(registerIp); | ||||||
|  |         userMapper.insert(user); | ||||||
|  |         return user; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void updateUserLogin(Long id, String loginIp) { |     public void updateUserLogin(Long id, String loginIp) { | ||||||
|         userMapper.updateById(new MbrUserDO().setId(id).setLoginIp(loginIp).setLoginDate(new Date())); |         userMapper.updateById(new MbrUserDO().setId(id).setLoginIp(loginIp).setLoginDate(new Date())); | ||||||
|  | |||||||
| @ -12,6 +12,20 @@ POST {{userServerUrl}}/send-sms-code | |||||||
| Content-Type: application/json | Content-Type: application/json | ||||||
|  |  | ||||||
| { | { | ||||||
|   "mobile": "15601691300", |   "mobile": "15601691301", | ||||||
|   "scene": 1 |   "scene": 1 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | ### 请求 /sms-login 接口 => 成功 | ||||||
|  | POST {{userServerUrl}}/sms-login | ||||||
|  | Content-Type: application/json | ||||||
|  |  | ||||||
|  | { | ||||||
|  |   "mobile": "15601691301", | ||||||
|  |   "code": 9999 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ### 请求 /logout 接口 => 成功 | ||||||
|  | POST {{userServerUrl}}/logout | ||||||
|  | Content-Type: application/json | ||||||
|  | Authorization: Bearer c1b76bdaf2c146c581caa4d7fd81ee66 | ||||||
|  | |||||||
| @ -33,28 +33,30 @@ public class SysAuthController { | |||||||
|  |  | ||||||
|     @PostMapping("/login") |     @PostMapping("/login") | ||||||
|     @ApiOperation("使用手机 + 密码登录") |     @ApiOperation("使用手机 + 密码登录") | ||||||
|     public CommonResult<MbrAuthLoginRespVO> login(@RequestBody @Valid SysAuthLoginReqVO reqVO) { |     public CommonResult<SysAuthLoginRespVO> login(@RequestBody @Valid SysAuthLoginReqVO reqVO) { | ||||||
|         String token = authService.login(reqVO, getClientIP(), getUserAgent()); |         String token = authService.login(reqVO, getClientIP(), getUserAgent()); | ||||||
|         // 返回结果 |         // 返回结果 | ||||||
|         return success(MbrAuthLoginRespVO.builder().token(token).build()); |         return success(SysAuthLoginRespVO.builder().token(token).build()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @PostMapping("/sms-login") |     @PostMapping("/sms-login") | ||||||
|     @ApiOperation("使用手机 + 验证码登录") |     @ApiOperation("使用手机 + 验证码登录") | ||||||
|     public CommonResult<MbrAuthLoginRespVO> smsLogin(@RequestBody @Valid SysAuthLoginReqVO reqVO) { |     public CommonResult<SysAuthLoginRespVO> smsLogin(@RequestBody @Valid SysAuthSmsLoginReqVO reqVO) { | ||||||
|         return null; |         String token = authService.smsLogin(reqVO, getClientIP(), getUserAgent()); | ||||||
|  |         // 返回结果 | ||||||
|  |         return success(SysAuthLoginRespVO.builder().token(token).build()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @PostMapping("/send-sms-code") |     @PostMapping("/send-sms-code") | ||||||
|     @ApiOperation("发送手机验证码") |     @ApiOperation("发送手机验证码") | ||||||
|     public CommonResult<Boolean> sendSmsCode(@RequestBody @Valid MbrAuthSendSmsReqVO reqVO) { |     public CommonResult<Boolean> sendSmsCode(@RequestBody @Valid SysAuthSendSmsReqVO reqVO) { | ||||||
|         smsCodeService.sendSmsCode(reqVO.getMobile(), reqVO.getScene(), getClientIP()); |         smsCodeService.sendSmsCode(reqVO.getMobile(), reqVO.getScene(), getClientIP()); | ||||||
|         return success(true); |         return success(true); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @PostMapping("/reset-password") |     @PostMapping("/reset-password") | ||||||
|     @ApiOperation(value = "重置密码", notes = "用户忘记密码时使用") |     @ApiOperation(value = "重置密码", notes = "用户忘记密码时使用") | ||||||
|     public CommonResult<Boolean> resetPassword(@RequestBody @Valid SysAuthResetPasswordReqVO reqVO) { |     public CommonResult<Boolean> resetPassword(@RequestBody @Valid MbrAuthResetPasswordReqVO reqVO) { | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -74,7 +76,7 @@ public class SysAuthController { | |||||||
|  |  | ||||||
|     @PostMapping("/social-login") |     @PostMapping("/social-login") | ||||||
|     @ApiOperation("社交登录,使用 code 授权码") |     @ApiOperation("社交登录,使用 code 授权码") | ||||||
|         public CommonResult<MbrAuthLoginRespVO> socialLogin(@RequestBody @Valid MbrAuthSocialLoginReqVO reqVO) { |         public CommonResult<SysAuthLoginRespVO> socialLogin(@RequestBody @Valid MbrAuthSocialLoginReqVO reqVO) { | ||||||
| //        String token = authService.socialLogin(reqVO, getClientIP(), getUserAgent()); | //        String token = authService.socialLogin(reqVO, getClientIP(), getUserAgent()); | ||||||
| //        // 返回结果 | //        // 返回结果 | ||||||
| //        return success(MbrAuthLoginRespVO.builder().token(token).build()); | //        return success(MbrAuthLoginRespVO.builder().token(token).build()); | ||||||
| @ -83,7 +85,7 @@ public class SysAuthController { | |||||||
|  |  | ||||||
|     @PostMapping("/social-login2") |     @PostMapping("/social-login2") | ||||||
|     @ApiOperation("社交登录,使用 code 授权码 + 账号密码") |     @ApiOperation("社交登录,使用 code 授权码 + 账号密码") | ||||||
|     public CommonResult<MbrAuthLoginRespVO> socialLogin2(@RequestBody @Valid MbrAuthSocialLogin2ReqVO reqVO) { |     public CommonResult<SysAuthLoginRespVO> socialLogin2(@RequestBody @Valid MbrAuthSocialLogin2ReqVO reqVO) { | ||||||
| //        String token = authService.socialLogin2(reqVO, getClientIP(), getUserAgent()); | //        String token = authService.socialLogin2(reqVO, getClientIP(), getUserAgent()); | ||||||
| //        // 返回结果 | //        // 返回结果 | ||||||
| //        return success(MbrAuthLoginRespVO.builder().token(token).build()); | //        return success(MbrAuthLoginRespVO.builder().token(token).build()); | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ import javax.validation.constraints.Pattern; | |||||||
| @NoArgsConstructor | @NoArgsConstructor | ||||||
| @AllArgsConstructor | @AllArgsConstructor | ||||||
| @Builder | @Builder | ||||||
| public class SysAuthResetPasswordReqVO { | public class MbrAuthResetPasswordReqVO { | ||||||
| 
 | 
 | ||||||
|     @ApiModelProperty(value = "新密码", required = true, example = "buzhidao") |     @ApiModelProperty(value = "新密码", required = true, example = "buzhidao") | ||||||
|     @NotEmpty(message = "新密码不能为空") |     @NotEmpty(message = "新密码不能为空") | ||||||
| @ -12,7 +12,7 @@ import lombok.NoArgsConstructor; | |||||||
| @NoArgsConstructor | @NoArgsConstructor | ||||||
| @AllArgsConstructor | @AllArgsConstructor | ||||||
| @Builder | @Builder | ||||||
| public class MbrAuthLoginRespVO { | public class SysAuthLoginRespVO { | ||||||
| 
 | 
 | ||||||
|     @ApiModelProperty(value = "token", required = true, example = "yudaoyuanma") |     @ApiModelProperty(value = "token", required = true, example = "yudaoyuanma") | ||||||
|     private String token; |     private String token; | ||||||
| @ -13,7 +13,7 @@ import javax.validation.constraints.NotNull; | |||||||
| @ApiModel("发送手机验证码 Response VO") | @ApiModel("发送手机验证码 Response VO") | ||||||
| @Data | @Data | ||||||
| @Accessors(chain = true) | @Accessors(chain = true) | ||||||
| public class MbrAuthSendSmsReqVO { | public class SysAuthSendSmsReqVO { | ||||||
| 
 | 
 | ||||||
|     @ApiModelProperty(value = "手机号", example = "15601691234") |     @ApiModelProperty(value = "手机号", example = "15601691234") | ||||||
|     @Mobile |     @Mobile | ||||||
| @ -17,18 +17,13 @@ import javax.validation.constraints.Pattern; | |||||||
| @NoArgsConstructor | @NoArgsConstructor | ||||||
| @AllArgsConstructor | @AllArgsConstructor | ||||||
| @Builder | @Builder | ||||||
| public class MbrAuthSmsLoginReqVO { | public class SysAuthSmsLoginReqVO { | ||||||
| 
 | 
 | ||||||
|     @ApiModelProperty(value = "手机号", required = true, example = "15601691300") |     @ApiModelProperty(value = "手机号", required = true, example = "15601691300") | ||||||
|     @NotEmpty(message = "手机号不能为空") |     @NotEmpty(message = "手机号不能为空") | ||||||
|     @Mobile |     @Mobile | ||||||
|     private String mobile; |     private String mobile; | ||||||
| 
 | 
 | ||||||
|     @ApiModelProperty(value = "密码", required = true, example = "buzhidao") |  | ||||||
|     @NotEmpty(message = "密码不能为空") |  | ||||||
|     @Length(min = 4, max = 16, message = "密码长度为 4-16 位") |  | ||||||
|     private String password; |  | ||||||
| 
 |  | ||||||
|     @ApiModelProperty(value = "手机验证码", required = true, example = "1024") |     @ApiModelProperty(value = "手机验证码", required = true, example = "1024") | ||||||
|     @NotEmpty(message = "手机验证码不能为空") |     @NotEmpty(message = "手机验证码不能为空") | ||||||
|     @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") |     @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") | ||||||
| @ -13,6 +13,7 @@ public interface SysErrorCodeConstants { | |||||||
|     ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1005000000, "登录失败,账号密码不正确"); |     ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1005000000, "登录失败,账号密码不正确"); | ||||||
|     ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1005000001, "登录失败,账号被禁用"); |     ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1005000001, "登录失败,账号被禁用"); | ||||||
|     ErrorCode AUTH_LOGIN_FAIL_UNKNOWN = new ErrorCode(1005000002, "登录失败"); // 登录失败的兜底,未知原因 |     ErrorCode AUTH_LOGIN_FAIL_UNKNOWN = new ErrorCode(1005000002, "登录失败"); // 登录失败的兜底,未知原因 | ||||||
|  |     ErrorCode AUTH_TOKEN_EXPIRED = new ErrorCode(1005000003, "Token 已经过期"); | ||||||
|  |  | ||||||
|     // ========== SMS CODE 模块 1005001000 ========== |     // ========== SMS CODE 模块 1005001000 ========== | ||||||
|     ErrorCode USER_SMS_CODE_NOT_FOUND = new ErrorCode(1005001000, "验证码不存在"); |     ErrorCode USER_SMS_CODE_NOT_FOUND = new ErrorCode(1005001000, "验证码不存在"); | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ package cn.iocoder.yudao.userserver.modules.system.service.auth; | |||||||
|  |  | ||||||
| import cn.iocoder.yudao.framework.security.core.service.SecurityAuthFrameworkService; | import cn.iocoder.yudao.framework.security.core.service.SecurityAuthFrameworkService; | ||||||
| import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthLoginReqVO; | import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthLoginReqVO; | ||||||
|  | import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthSmsLoginReqVO; | ||||||
|  |  | ||||||
| import javax.validation.Valid; | import javax.validation.Valid; | ||||||
|  |  | ||||||
| @ -24,4 +25,14 @@ public interface SysAuthService extends SecurityAuthFrameworkService { | |||||||
|      */ |      */ | ||||||
|     String login(@Valid SysAuthLoginReqVO reqVO, String userIp, String userAgent); |     String login(@Valid SysAuthLoginReqVO reqVO, String userIp, String userAgent); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 手机 + 验证码登陆 | ||||||
|  |      * | ||||||
|  |      * @param reqVO 登陆信息 | ||||||
|  |      * @param userIp 用户 IP | ||||||
|  |      * @param userAgent 用户 UA | ||||||
|  |      * @return 身份令牌,使用 JWT 方式 | ||||||
|  |      */ | ||||||
|  |     String smsLogin(@Valid SysAuthSmsLoginReqVO reqVO, String userIp, String userAgent); | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,18 +1,24 @@ | |||||||
| package cn.iocoder.yudao.userserver.modules.system.service.auth.impl; | package cn.iocoder.yudao.userserver.modules.system.service.auth.impl; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.lang.Assert; | ||||||
| import cn.iocoder.yudao.coreservice.modules.system.service.auth.SysUserSessionCoreService; | import cn.iocoder.yudao.coreservice.modules.system.service.auth.SysUserSessionCoreService; | ||||||
| import cn.iocoder.yudao.coreservice.modules.system.service.logger.SysLoginLogCoreService; | import cn.iocoder.yudao.coreservice.modules.system.service.logger.SysLoginLogCoreService; | ||||||
| import cn.iocoder.yudao.coreservice.modules.system.service.logger.dto.SysLoginLogCreateReqDTO; | import cn.iocoder.yudao.coreservice.modules.system.service.logger.dto.SysLoginLogCreateReqDTO; | ||||||
|  | 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.monitor.TracerUtils; | ||||||
| import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; | import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; | ||||||
| import cn.iocoder.yudao.framework.security.core.LoginUser; | import cn.iocoder.yudao.framework.security.core.LoginUser; | ||||||
| import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthLoginReqVO; | import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthLoginReqVO; | ||||||
|  | import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthSmsLoginReqVO; | ||||||
| import cn.iocoder.yudao.userserver.modules.system.convert.auth.SysAuthConvert; | import cn.iocoder.yudao.userserver.modules.system.convert.auth.SysAuthConvert; | ||||||
| import cn.iocoder.yudao.userserver.modules.member.dal.dataobject.user.MbrUserDO; | import cn.iocoder.yudao.userserver.modules.member.dal.dataobject.user.MbrUserDO; | ||||||
|  | import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; | ||||||
| import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService; | import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService; | ||||||
| import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; | import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; | ||||||
| import cn.iocoder.yudao.coreservice.modules.system.enums.logger.SysLoginLogTypeEnum; | import cn.iocoder.yudao.coreservice.modules.system.enums.logger.SysLoginLogTypeEnum; | ||||||
| import cn.iocoder.yudao.coreservice.modules.system.enums.logger.SysLoginResultEnum; | import cn.iocoder.yudao.coreservice.modules.system.enums.logger.SysLoginResultEnum; | ||||||
|  | import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; | ||||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||||
| import org.springframework.context.annotation.Lazy; | import org.springframework.context.annotation.Lazy; | ||||||
| import org.springframework.security.authentication.AuthenticationManager; | import org.springframework.security.authentication.AuthenticationManager; | ||||||
| @ -24,7 +30,7 @@ import org.springframework.security.core.AuthenticationException; | |||||||
| import org.springframework.security.core.userdetails.UserDetails; | import org.springframework.security.core.userdetails.UserDetails; | ||||||
| import org.springframework.security.core.userdetails.UsernameNotFoundException; | import org.springframework.security.core.userdetails.UsernameNotFoundException; | ||||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||||
| import org.springframework.util.Assert; | import org.springframework.transaction.annotation.Transactional; | ||||||
|  |  | ||||||
| import javax.annotation.Resource; | import javax.annotation.Resource; | ||||||
| import java.util.Objects; | import java.util.Objects; | ||||||
| @ -48,6 +54,8 @@ public class SysAuthServiceImpl implements SysAuthService { | |||||||
|     @Resource |     @Resource | ||||||
|     private MbrUserService userService; |     private MbrUserService userService; | ||||||
|     @Resource |     @Resource | ||||||
|  |     private SysSmsCodeService smsCodeService; | ||||||
|  |     @Resource | ||||||
|     private SysLoginLogCoreService loginLogCoreService; |     private SysLoginLogCoreService loginLogCoreService; | ||||||
|     @Resource |     @Resource | ||||||
|     private SysUserSessionCoreService userSessionCoreService; |     private SysUserSessionCoreService userSessionCoreService; | ||||||
| @ -72,6 +80,25 @@ public class SysAuthServiceImpl implements SysAuthService { | |||||||
|         return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); |         return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     @Transactional | ||||||
|  |     public String smsLogin(SysAuthSmsLoginReqVO reqVO, String userIp, String userAgent) { | ||||||
|  |         // 校验验证码 | ||||||
|  |         smsCodeService.useSmsCode(reqVO.getMobile(), SysSmsSceneEnum.LOGIN_BY_SMS.getScene(), | ||||||
|  |                 reqVO.getCode(), userIp); | ||||||
|  |  | ||||||
|  |         // 获得获得注册用户 | ||||||
|  |         MbrUserDO user = userService.createUserIfAbsent(reqVO.getMobile(), userIp); | ||||||
|  |         Assert.notNull(user, "获取用户失败,结果为空"); | ||||||
|  |  | ||||||
|  |         // 执行登陆 | ||||||
|  |         this.createLoginLog(user.getMobile(), SysLoginLogTypeEnum.LOGIN_SMS, SysLoginResultEnum.SUCCESS); | ||||||
|  |         LoginUser loginUser = SysAuthConvert.INSTANCE.convert(user); | ||||||
|  |  | ||||||
|  |         // 缓存登录用户到 Redis 中,返回 sessionId 编号 | ||||||
|  |         return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     private LoginUser login0(String username, String password) { |     private LoginUser login0(String username, String password) { | ||||||
|         final SysLoginLogTypeEnum logTypeEnum = SysLoginLogTypeEnum.LOGIN_USERNAME; |         final SysLoginLogTypeEnum logTypeEnum = SysLoginLogTypeEnum.LOGIN_USERNAME; | ||||||
|         // 用户验证 |         // 用户验证 | ||||||
| @ -120,7 +147,31 @@ public class SysAuthServiceImpl implements SysAuthService { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public LoginUser verifyTokenAndRefresh(String token) { |     public LoginUser verifyTokenAndRefresh(String token) { | ||||||
|         return null; |         // 获得 LoginUser | ||||||
|  |         LoginUser loginUser = userSessionCoreService.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() < | ||||||
|  |                 userSessionCoreService.getSessionTimeoutMillis() / 3) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // 重新加载 MbrUserDO 信息 | ||||||
|  |         MbrUserDO user = userService.getUser(loginUser.getId()); | ||||||
|  |         if (user == null || CommonStatusEnum.DISABLE.getStatus().equals(user.getStatus())) { | ||||||
|  |             throw exception(AUTH_TOKEN_EXPIRED); // 校验 token 时,用户被禁用的情况下,也认为 token 过期,方便前端跳转到登录界面 | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // 刷新 LoginUser 缓存 | ||||||
|  |         userSessionCoreService.refreshUserSession(token, loginUser); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
| @ -130,6 +181,8 @@ public class SysAuthServiceImpl implements SysAuthService { | |||||||
|         if (user == null) { |         if (user == null) { | ||||||
|             throw new UsernameNotFoundException(String.valueOf(userId)); |             throw new UsernameNotFoundException(String.valueOf(userId)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         // 执行登陆 | ||||||
|         this.createLoginLog(user.getMobile(), SysLoginLogTypeEnum.LOGIN_MOCK, SysLoginResultEnum.SUCCESS); |         this.createLoginLog(user.getMobile(), SysLoginLogTypeEnum.LOGIN_MOCK, SysLoginResultEnum.SUCCESS); | ||||||
|  |  | ||||||
|         // 创建 LoginUser 对象 |         // 创建 LoginUser 对象 | ||||||
| @ -138,7 +191,28 @@ public class SysAuthServiceImpl implements SysAuthService { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void logout(String token) { |     public void logout(String token) { | ||||||
|  |         // 查询用户信息 | ||||||
|  |         LoginUser loginUser = userSessionCoreService.getLoginUser(token); | ||||||
|  |         if (loginUser == null) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         // 删除 session | ||||||
|  |         userSessionCoreService.deleteUserSession(token); | ||||||
|  |         // 记录登出日志 | ||||||
|  |         this.createLogoutLog(loginUser.getId(), loginUser.getUsername()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void createLogoutLog(Long userId, String username) { | ||||||
|  |         SysLoginLogCreateReqDTO reqDTO = new SysLoginLogCreateReqDTO(); | ||||||
|  |         reqDTO.setLogType(SysLoginLogTypeEnum.LOGOUT_SELF.getType()); | ||||||
|  |         reqDTO.setTraceId(TracerUtils.getTraceId()); | ||||||
|  |         reqDTO.setUserId(userId); | ||||||
|  |         reqDTO.setUserType(UserTypeEnum.MEMBER.getValue()); | ||||||
|  |         reqDTO.setUsername(username); | ||||||
|  |         reqDTO.setUserAgent(ServletUtils.getUserAgent()); | ||||||
|  |         reqDTO.setUserIp(ServletUtils.getClientIP()); | ||||||
|  |         reqDTO.setResult(SysLoginResultEnum.SUCCESS.getResult()); | ||||||
|  |         loginLogCoreService.createLoginLog(reqDTO); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV