diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysErrorCodeConstants.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysErrorCodeConstants.java index 72f6ac671..581f99b85 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysErrorCodeConstants.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysErrorCodeConstants.java @@ -16,10 +16,7 @@ public interface SysErrorCodeConstants { ErrorCode AUTH_LOGIN_CAPTCHA_NOT_FOUND = new ErrorCode(1002000003, "验证码不存在"); ErrorCode AUTH_LOGIN_CAPTCHA_CODE_ERROR = new ErrorCode(1002000004, "验证码不正确"); ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1002000005, "未绑定账号,需要进行绑定"); - - // ========== TOKEN 模块 1002001000 ========== - ErrorCode TOKEN_EXPIRED = new ErrorCode(1002001000, "Token 已经过期"); - ErrorCode TOKEN_PARSE_FAIL = new ErrorCode(1002001001, "Token 解析失败"); + ErrorCode AUTH_TOKEN_EXPIRED = new ErrorCode(1002000006, "Token 已经过期"); // ========== 菜单模块 1002002000 ========== ErrorCode MENU_NAME_DUPLICATE = new ErrorCode(1002002000, "已经存在该名字的菜单"); diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java index bfa583925..e7752f1df 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java @@ -255,15 +255,15 @@ public class SysAuthServiceImpl implements SysAuthService { } // 删除 session userSessionCoreService.deleteUserSession(token); - // 记录登出日子和 - this.createLogoutLog(loginUser.getUsername()); + // 记录登出日志 + this.createLogoutLog(loginUser.getId(), loginUser.getUsername()); } - private void createLogoutLog(String username) { - // TODO 芋艿:这里未设置 userId + 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.ADMIN.getValue()); reqDTO.setUsername(username); reqDTO.setUserAgent(ServletUtils.getUserAgent()); @@ -294,7 +294,7 @@ public class SysAuthServiceImpl implements SysAuthService { // 重新加载 SysUserDO 信息 SysUserDO user = userService.getUser(loginUser.getId()); if (user == null || CommonStatusEnum.DISABLE.getStatus().equals(user.getStatus())) { - throw exception(TOKEN_EXPIRED); // 校验 token 时,用户被禁用的情况下,也认为 token 过期,方便前端跳转到登录界面 + throw exception(AUTH_TOKEN_EXPIRED); // 校验 token 时,用户被禁用的情况下,也认为 token 过期,方便前端跳转到登录界面 } // 刷新 LoginUser 缓存 diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java index 9a53d429a..886fa012f 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java @@ -1,5 +1,6 @@ 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; /** @@ -17,6 +18,16 @@ public interface MbrUserService { */ MbrUserDO getUserByMobile(String mobile); + /** + * 基于手机号创建用户。 + * 如果用户已经存在,则直接进行返回 + * + * @param mobile 手机号 + * @param registerIp 注册 IP + * @return 用户对象 + */ + MbrUserDO createUserIfAbsent(@Mobile String mobile, String registerIp); + /** * 更新用户的最后登陆信息 * diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java index ea15c4156..51faf189c 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java @@ -1,9 +1,14 @@ 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.mysql.user.MbrUserMapper; import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; import lombok.extern.slf4j.Slf4j; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -23,11 +28,38 @@ public class MbrUserServiceImpl implements MbrUserService { @Resource private MbrUserMapper userMapper; + @Resource + private PasswordEncoder passwordEncoder; + @Override public MbrUserDO getUserByMobile(String 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 public void updateUserLogin(Long id, String loginIp) { userMapper.updateById(new MbrUserDO().setId(id).setLoginIp(loginIp).setLoginDate(new Date())); diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.http b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.http index af42933fb..e02af92a1 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.http +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.http @@ -12,6 +12,20 @@ POST {{userServerUrl}}/send-sms-code Content-Type: application/json { - "mobile": "15601691300", + "mobile": "15601691301", "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 diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.java index 18058bdd3..2b1fd6161 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.java @@ -33,28 +33,30 @@ public class SysAuthController { @PostMapping("/login") @ApiOperation("使用手机 + 密码登录") - public CommonResult login(@RequestBody @Valid SysAuthLoginReqVO reqVO) { + public CommonResult login(@RequestBody @Valid SysAuthLoginReqVO reqVO) { String token = authService.login(reqVO, getClientIP(), getUserAgent()); // 返回结果 - return success(MbrAuthLoginRespVO.builder().token(token).build()); + return success(SysAuthLoginRespVO.builder().token(token).build()); } @PostMapping("/sms-login") @ApiOperation("使用手机 + 验证码登录") - public CommonResult smsLogin(@RequestBody @Valid SysAuthLoginReqVO reqVO) { - return null; + public CommonResult smsLogin(@RequestBody @Valid SysAuthSmsLoginReqVO reqVO) { + String token = authService.smsLogin(reqVO, getClientIP(), getUserAgent()); + // 返回结果 + return success(SysAuthLoginRespVO.builder().token(token).build()); } @PostMapping("/send-sms-code") @ApiOperation("发送手机验证码") - public CommonResult sendSmsCode(@RequestBody @Valid MbrAuthSendSmsReqVO reqVO) { + public CommonResult sendSmsCode(@RequestBody @Valid SysAuthSendSmsReqVO reqVO) { smsCodeService.sendSmsCode(reqVO.getMobile(), reqVO.getScene(), getClientIP()); return success(true); } @PostMapping("/reset-password") @ApiOperation(value = "重置密码", notes = "用户忘记密码时使用") - public CommonResult resetPassword(@RequestBody @Valid SysAuthResetPasswordReqVO reqVO) { + public CommonResult resetPassword(@RequestBody @Valid MbrAuthResetPasswordReqVO reqVO) { return null; } @@ -74,7 +76,7 @@ public class SysAuthController { @PostMapping("/social-login") @ApiOperation("社交登录,使用 code 授权码") - public CommonResult socialLogin(@RequestBody @Valid MbrAuthSocialLoginReqVO reqVO) { + public CommonResult socialLogin(@RequestBody @Valid MbrAuthSocialLoginReqVO reqVO) { // String token = authService.socialLogin(reqVO, getClientIP(), getUserAgent()); // // 返回结果 // return success(MbrAuthLoginRespVO.builder().token(token).build()); @@ -83,7 +85,7 @@ public class SysAuthController { @PostMapping("/social-login2") @ApiOperation("社交登录,使用 code 授权码 + 账号密码") - public CommonResult socialLogin2(@RequestBody @Valid MbrAuthSocialLogin2ReqVO reqVO) { + public CommonResult socialLogin2(@RequestBody @Valid MbrAuthSocialLogin2ReqVO reqVO) { // String token = authService.socialLogin2(reqVO, getClientIP(), getUserAgent()); // // 返回结果 // return success(MbrAuthLoginRespVO.builder().token(token).build()); diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthResetPasswordReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthResetPasswordReqVO.java similarity index 96% rename from yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthResetPasswordReqVO.java rename to yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthResetPasswordReqVO.java index 01e438cb7..3b3556fdb 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthResetPasswordReqVO.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthResetPasswordReqVO.java @@ -16,7 +16,7 @@ import javax.validation.constraints.Pattern; @NoArgsConstructor @AllArgsConstructor @Builder -public class SysAuthResetPasswordReqVO { +public class MbrAuthResetPasswordReqVO { @ApiModelProperty(value = "新密码", required = true, example = "buzhidao") @NotEmpty(message = "新密码不能为空") diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthLoginRespVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthLoginRespVO.java similarity index 93% rename from yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthLoginRespVO.java rename to yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthLoginRespVO.java index 1601baa4a..95c69c754 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthLoginRespVO.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthLoginRespVO.java @@ -12,7 +12,7 @@ import lombok.NoArgsConstructor; @NoArgsConstructor @AllArgsConstructor @Builder -public class MbrAuthLoginRespVO { +public class SysAuthLoginRespVO { @ApiModelProperty(value = "token", required = true, example = "yudaoyuanma") private String token; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSendSmsReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthSendSmsReqVO.java similarity index 96% rename from yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSendSmsReqVO.java rename to yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthSendSmsReqVO.java index 6ce41ca22..d8c6c983f 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSendSmsReqVO.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthSendSmsReqVO.java @@ -13,7 +13,7 @@ import javax.validation.constraints.NotNull; @ApiModel("发送手机验证码 Response VO") @Data @Accessors(chain = true) -public class MbrAuthSendSmsReqVO { +public class SysAuthSendSmsReqVO { @ApiModelProperty(value = "手机号", example = "15601691234") @Mobile diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSmsLoginReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthSmsLoginReqVO.java similarity index 80% rename from yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSmsLoginReqVO.java rename to yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthSmsLoginReqVO.java index 56b4e50e4..a7b36bb54 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSmsLoginReqVO.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthSmsLoginReqVO.java @@ -17,18 +17,13 @@ import javax.validation.constraints.Pattern; @NoArgsConstructor @AllArgsConstructor @Builder -public class MbrAuthSmsLoginReqVO { +public class SysAuthSmsLoginReqVO { @ApiModelProperty(value = "手机号", required = true, example = "15601691300") @NotEmpty(message = "手机号不能为空") @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") @NotEmpty(message = "手机验证码不能为空") @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/SysErrorCodeConstants.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/SysErrorCodeConstants.java index 3abcab559..e5f4ac678 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/SysErrorCodeConstants.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/SysErrorCodeConstants.java @@ -13,6 +13,7 @@ public interface SysErrorCodeConstants { ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1005000000, "登录失败,账号密码不正确"); ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1005000001, "登录失败,账号被禁用"); ErrorCode AUTH_LOGIN_FAIL_UNKNOWN = new ErrorCode(1005000002, "登录失败"); // 登录失败的兜底,未知原因 + ErrorCode AUTH_TOKEN_EXPIRED = new ErrorCode(1005000003, "Token 已经过期"); // ========== SMS CODE 模块 1005001000 ========== ErrorCode USER_SMS_CODE_NOT_FOUND = new ErrorCode(1005001000, "验证码不存在"); diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/SysAuthService.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/SysAuthService.java index b560f9d78..b35d1c27a 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/SysAuthService.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/SysAuthService.java @@ -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.userserver.modules.system.controller.auth.vo.SysAuthLoginReqVO; +import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthSmsLoginReqVO; import javax.validation.Valid; @@ -24,4 +25,14 @@ public interface SysAuthService extends SecurityAuthFrameworkService { */ 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); + } diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java index 0c84cfcea..1baaa24a3 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java @@ -1,18 +1,24 @@ 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.logger.SysLoginLogCoreService; 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.servlet.ServletUtils; 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.SysAuthSmsLoginReqVO; 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.system.enums.sms.SysSmsSceneEnum; import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService; 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.SysLoginResultEnum; +import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; 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.UsernameNotFoundException; import org.springframework.stereotype.Service; -import org.springframework.util.Assert; +import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.Objects; @@ -48,6 +54,8 @@ public class SysAuthServiceImpl implements SysAuthService { @Resource private MbrUserService userService; @Resource + private SysSmsCodeService smsCodeService; + @Resource private SysLoginLogCoreService loginLogCoreService; @Resource private SysUserSessionCoreService userSessionCoreService; @@ -72,6 +80,25 @@ public class SysAuthServiceImpl implements SysAuthService { 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) { final SysLoginLogTypeEnum logTypeEnum = SysLoginLogTypeEnum.LOGIN_USERNAME; // 用户验证 @@ -120,7 +147,31 @@ public class SysAuthServiceImpl implements SysAuthService { @Override 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 @@ -130,6 +181,8 @@ public class SysAuthServiceImpl implements SysAuthService { if (user == null) { throw new UsernameNotFoundException(String.valueOf(userId)); } + + // 执行登陆 this.createLoginLog(user.getMobile(), SysLoginLogTypeEnum.LOGIN_MOCK, SysLoginResultEnum.SUCCESS); // 创建 LoginUser 对象 @@ -138,7 +191,28 @@ public class SysAuthServiceImpl implements SysAuthService { @Override 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); } }