From 08cfe71646aca782c59ca4977e79d17c758af0ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=8B=E5=A4=A9?= <2982176321@qq.com> Date: Sun, 19 Dec 2021 19:28:01 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=87=8D=E7=BD=AE?= =?UTF-8?q?=E6=89=8B=E6=9C=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-user-server/pom.xml | 9 --- .../user/SysUserProfileController.java | 7 -- .../user/vo/MbrUserUpdateMobileReqVO.java | 17 ++++- .../service/user/impl/MbrUserServiceImpl.java | 29 +++++-- .../controller/auth/SysAuthController.java | 8 -- .../auth/vo/MbrAuthResetPasswordReqVO.java | 6 ++ .../auth/vo/SysAuthCheckCodeReqVO.java | 40 ++++++++++ .../dal/mysql/sms/SysSmsCodeMapper.java | 6 +- .../system/enums/SysErrorCodeConstants.java | 2 +- .../system/service/auth/SysAuthService.java | 9 +-- .../service/auth/impl/SysAuthServiceImpl.java | 51 ++++++------- .../system/service/sms/SysSmsCodeService.java | 13 ++++ .../sms/impl/SysSmsCodeServiceImpl.java | 38 +++++----- .../SysUserProfileControllerTest.java | 60 --------------- .../controller/SysAuthControllerTest.java | 75 ------------------- 15 files changed, 146 insertions(+), 224 deletions(-) create mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthCheckCodeReqVO.java delete mode 100644 yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/member/controller/SysUserProfileControllerTest.java delete mode 100644 yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/system/controller/SysAuthControllerTest.java diff --git a/yudao-user-server/pom.xml b/yudao-user-server/pom.xml index 03dbfd699..be4005835 100644 --- a/yudao-user-server/pom.xml +++ b/yudao-user-server/pom.xml @@ -90,15 +90,6 @@ yudao-spring-boot-starter-test test - - - - - junit - junit - test - - diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.java index 93149e793..ae10719ce 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.java @@ -35,9 +35,6 @@ public class SysUserProfileController { @Resource private MbrUserService userService; - @Resource - private SysSmsCodeService smsCodeService; - @PutMapping("/update-nickname") @ApiOperation("修改用户昵称") @PreAuthenticated @@ -68,10 +65,6 @@ public class SysUserProfileController { @ApiOperation(value = "修改用户手机") @PreAuthenticated public CommonResult updateMobile(@RequestBody @Valid MbrUserUpdateMobileReqVO reqVO) { - // 校验验证码 - // TODO @宋天:统一到 userService.updateMobile 方法里 - smsCodeService.useSmsCode(reqVO.getMobile(),SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene(), reqVO.getCode(),getClientIP()); - userService.updateMobile(getLoginUserId(), reqVO); return success(true); } diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/vo/MbrUserUpdateMobileReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/vo/MbrUserUpdateMobileReqVO.java index df1980b89..8593302d7 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/vo/MbrUserUpdateMobileReqVO.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/vo/MbrUserUpdateMobileReqVO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.userserver.modules.member.controller.user.vo; +import cn.iocoder.yudao.framework.common.validation.Mobile; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; @@ -27,9 +28,21 @@ public class MbrUserUpdateMobileReqVO { @ApiModelProperty(value = "手机号",required = true,example = "15823654487") @NotBlank(message = "手机号不能为空") - // TODO @宋天:手机校验,直接使用 @Mobile 哈 @Length(min = 8, max = 11, message = "手机号码长度为 8-11 位") - @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式错误") + @Mobile private String mobile; + @ApiModelProperty(value = "原手机验证码", required = true, example = "1024") + @NotEmpty(message = "原手机验证码不能为空") + @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") + @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") + private String oldCode; + + @ApiModelProperty(value = "原手机号",required = true,example = "15823654487") + @NotBlank(message = "手机号不能为空") + @Length(min = 8, max = 11, message = "手机号码长度为 8-11 位") + @Mobile + private String oldMobile; + + } 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 f45ad257b..acfc489de 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 @@ -9,7 +9,10 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserUpdateMobileReqVO; 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.system.dal.dataobject.sms.SysSmsCodeDO; +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.sms.SysSmsCodeService; import com.google.common.annotations.VisibleForTesting; import lombok.extern.slf4j.Slf4j; import org.springframework.security.crypto.password.PasswordEncoder; @@ -21,7 +24,10 @@ import java.io.InputStream; import java.util.Date; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; import static cn.iocoder.yudao.userserver.modules.member.enums.MbrErrorCodeConstants.USER_NOT_EXISTS; +import static cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConstants.USER_SMS_CODE_IS_UNUSED; +import static cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConstants.USER_SMS_CODE_NOT_CORRECT; /** * User Service 实现类 @@ -45,6 +51,10 @@ public class MbrUserServiceImpl implements MbrUserService { @Resource private SysAuthService sysAuthService; + @Resource + private SysSmsCodeService smsCodeService; + + @Override public MbrUserDO getUserByMobile(String mobile) { return userMapper.selectByMobile(mobile); @@ -124,12 +134,21 @@ public class MbrUserServiceImpl implements MbrUserService { @Override public void updateMobile(Long userId, MbrUserUpdateMobileReqVO reqVO) { // 检测用户是否存在 - MbrUserDO userDO = checkUserExists(userId); - // 检测手机与验证码是否匹配 - // TODO @宋天:修改手机的时候。应该要校验,老手机 + 老手机 code;新手机 + 新手机 code - sysAuthService.checkIfMobileMatchCodeAndDeleteCode(userDO.getMobile(),reqVO.getCode()); + checkUserExists(userId); + // 校验验证码,并标记为已使用 + smsCodeService.useSmsCode(reqVO.getMobile(), SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene(), reqVO.getCode(),getClientIP()); + + // 检测新手机和旧手机的验证码是否在30分钟内 + SysSmsCodeDO smsOldCodeDO = smsCodeService.checkCodeIsExpired(reqVO.getOldMobile(), reqVO.getOldCode(), SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene()); + SysSmsCodeDO smsNewCodeDO = smsCodeService.checkCodeIsExpired(reqVO.getMobile(), reqVO.getCode(), SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene()); + + // 判断新旧code是否未被使用,如果是,抛出异常 + if (Boolean.FALSE.equals(smsOldCodeDO.getUsed()) || Boolean.FALSE.equals(smsNewCodeDO.getUsed())){ + throw exception(USER_SMS_CODE_IS_UNUSED); + } + // 更新用户手机 - // TODO @宋天:更新的时候,单独创建对象。直接全量更新,会可能导致属性覆盖。可以看看打印出来的 SQL 哈 + MbrUserDO userDO = MbrUserDO.builder().build(); userDO.setMobile(reqVO.getMobile()); userMapper.updateById(userDO); } 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 9e6b9f450..dcc98e402 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 @@ -93,14 +93,6 @@ public class SysAuthController { return success(true); } - @PostMapping("/check-sms-code") - @ApiOperation(value = "校验验证码是否正确") - @PreAuthenticated - public CommonResult checkSmsCode(@RequestBody @Valid SysAuthSmsLoginReqVO reqVO) { - // TODO @宋天:check 的时候,不应该使用 useSmsCode 哈,这样验证码就直接被使用了。另外,check 开头的方法,更多是校验的逻辑,不会有 update 数据的动作。这点,在方法命名上,也是要注意的 - smsCodeService.useSmsCode(reqVO.getMobile(),SysSmsSceneEnum.CHECK_CODE_BY_SMS.getScene(),reqVO.getCode(),getClientIP()); - return success(true); - } // ========== 社交登录相关 ========== diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthResetPasswordReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthResetPasswordReqVO.java index 3b3556fdb..816017455 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthResetPasswordReqVO.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthResetPasswordReqVO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; +import cn.iocoder.yudao.framework.common.validation.Mobile; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; @@ -8,6 +9,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.hibernate.validator.constraints.Length; +import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; @@ -29,4 +31,8 @@ public class MbrAuthResetPasswordReqVO { @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") private String code; + @ApiModelProperty(value = "手机号",required = true,example = "15878962356") + @NotBlank(message = "手机号不能为空") + @Mobile + private String mobile; } diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthCheckCodeReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthCheckCodeReqVO.java new file mode 100644 index 000000000..89f1f501e --- /dev/null +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthCheckCodeReqVO.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; + +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.framework.common.validation.Mobile; +import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +@ApiModel("校验验证码 Request VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class SysAuthCheckCodeReqVO { + + @ApiModelProperty(value = "手机号", example = "15601691234") + @NotBlank(message = "手机号不能为空") + @Mobile + private String mobile; + + @ApiModelProperty(value = "手机验证码", required = true, example = "1024") + @NotBlank(message = "手机验证码不能为空") + @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") + @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") + private String code; + + @ApiModelProperty(value = "发送场景", example = "1", notes = "对应 MbrSmsSceneEnum 枚举") + @NotNull(message = "发送场景不能为空") + @InEnum(SysSmsSceneEnum.class) + private Integer scene; +} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/sms/SysSmsCodeMapper.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/sms/SysSmsCodeMapper.java index 6ef96ca1f..88e10363f 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/sms/SysSmsCodeMapper.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/sms/SysSmsCodeMapper.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; import org.apache.ibatis.annotations.Mapper; + @Mapper public interface SysSmsCodeMapper extends BaseMapperX { @@ -13,14 +14,15 @@ public interface SysSmsCodeMapper extends BaseMapperX { * * @param mobile 手机号 * @param scene 发送场景,选填 + * @param code 验证码 选填 * @return 手机验证码 */ - default SysSmsCodeDO selectLastByMobile(String mobile, Integer scene) { + default SysSmsCodeDO selectLastByMobile(String mobile,String code,Integer scene) { return selectOne(new QueryWrapperX() .eq("mobile", mobile) .eqIfPresent("scene", scene) + .eqIfPresent("code", code) .orderByDesc("id") .last("LIMIT 1")); } - } 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 e7c104afb..c37dca9b0 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 @@ -24,9 +24,9 @@ public interface SysErrorCodeConstants { ErrorCode USER_SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY = new ErrorCode(1005001004, "超过每日短信发送数量"); ErrorCode USER_SMS_CODE_SEND_TOO_FAST = new ErrorCode(1005001005, "短信发送过于频率"); ErrorCode USER_SMS_CODE_IS_EXISTS = new ErrorCode(1005001006, "手机号已被使用"); + ErrorCode USER_SMS_CODE_IS_UNUSED = new ErrorCode(1005001006, "手机号未被使用"); // ========== 用户模块 1005002000 ========== ErrorCode USER_NOT_EXISTS = new ErrorCode(1005002001, "用户不存在"); - ErrorCode USER_CODE_FAILED = new ErrorCode(1005002002, "验证码不匹配"); ErrorCode USER_PASSWORD_FAILED = new ErrorCode(1005002003, "密码校验失败"); } 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 33664d351..62cb2e716 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 @@ -68,18 +68,11 @@ public interface SysAuthService extends SecurityAuthFrameworkService { * @param userId 用户id * @param userReqVO 用户请求实体类 */ - void updatePassword(Long userId, @Valid MbrAuthUpdatePasswordReqVO userReqVO); + void updatePassword(Long userId,MbrAuthUpdatePasswordReqVO userReqVO); /** * 忘记密码 * @param userReqVO 用户请求实体类 */ void resetPassword(MbrAuthResetPasswordReqVO userReqVO); - - /** - * 检测手机与验证码是否匹配 - * @param phone 手机号 - * @param code 验证码 - */ - void checkIfMobileMatchCodeAndDeleteCode(String phone,String code); } 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 f4193b35b..756f50f22 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 @@ -280,46 +280,30 @@ public class SysAuthServiceImpl implements SysAuthService { } @Override - public void updatePassword(Long userId, @Valid MbrAuthUpdatePasswordReqVO reqVO) { + public void updatePassword(Long userId,MbrAuthUpdatePasswordReqVO reqVO) { // 检验旧密码 MbrUserDO userDO = checkOldPassword(userId, reqVO.getOldPassword()); // 更新用户密码 - // TODO @宋天:不要更新整个对象哈 - userDO.setPassword(passwordEncoder.encode(reqVO.getPassword())); - userMapper.updateById(userDO); + MbrUserDO mbrUserDO = MbrUserDO.builder().build(); + mbrUserDO.setId(userDO.getId()); + mbrUserDO.setPassword(passwordEncoder.encode(reqVO.getPassword())); + userMapper.updateById(mbrUserDO); } @Override public void resetPassword(MbrAuthResetPasswordReqVO reqVO) { - // 根据验证码取出手机号,并查询用户 - String mobile = stringRedisTemplate.opsForValue().get(reqVO.getCode()); - MbrUserDO userDO = userMapper.selectByMobile(mobile); - if (userDO == null){ - throw exception(USER_NOT_EXISTS); - } - // TODO @芋艿 这一步没必要检验验证码与手机是否匹配,因为是根据验证码去redis中查找手机号,然后根据手机号查询用户 - // 也就是说 即便黑客以其他方式将验证码发送到自己手机上,最终还是会根据手机号查询用户然后进行重置密码的操作,不存在安全问题 + // 检验用户是否存在 + MbrUserDO userDO = checkUserIfExists(reqVO.getMobile()); - // TODO @宋天:这块微信在讨论下哈~~~ - - // 校验验证码 - smsCodeService.useSmsCode(userDO.getMobile(), SysSmsSceneEnum.FORGET_MOBILE_BY_SMS.getScene(), reqVO.getCode(),getClientIP()); + // 使用验证码 + smsCodeService.useSmsCode(reqVO.getMobile(),SysSmsSceneEnum.FORGET_MOBILE_BY_SMS.getScene(),reqVO.getCode(),getClientIP()); // 更新密码 - userDO.setPassword(passwordEncoder.encode(reqVO.getPassword())); - userMapper.updateById(userDO); - } - - @Override - public void checkIfMobileMatchCodeAndDeleteCode(String phone, String code) { - // 检验用户手机与验证码是否匹配 - String mobile = stringRedisTemplate.opsForValue().get(code); - if (!phone.equals(mobile)){ - throw exception(USER_CODE_FAILED); - } - // 销毁redis中此验证码 - stringRedisTemplate.delete(code); + MbrUserDO mbrUserDO = MbrUserDO.builder().build(); + mbrUserDO.setId(userDO.getId()); + mbrUserDO.setPassword(passwordEncoder.encode(reqVO.getPassword())); + userMapper.updateById(mbrUserDO); } /** @@ -342,6 +326,15 @@ public class SysAuthServiceImpl implements SysAuthService { return user; } + public MbrUserDO checkUserIfExists(String mobile) { + MbrUserDO user = userMapper.selectByMobile(mobile); + if (user == null) { + throw exception(USER_NOT_EXISTS); + } + return user; + } + + private void createLogoutLog(Long userId, String username) { SysLoginLogCreateReqDTO reqDTO = new SysLoginLogCreateReqDTO(); reqDTO.setLogType(SysLoginLogTypeEnum.LOGOUT_SELF.getType()); diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java index 6e9c3c7b3..160527d35 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java @@ -2,7 +2,10 @@ package cn.iocoder.yudao.userserver.modules.system.service.sms; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.validation.Mobile; +import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthCheckCodeReqVO; import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthSendSmsReqVO; +import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthSmsLoginReqVO; +import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; /** @@ -44,4 +47,14 @@ public interface SysSmsCodeService { * @param userId 用户id */ void sendSmsCodeLogin(Long userId); + + /** + * 检测手机验证码是否有效 + * @param mobile 手机号 + * @param code 验证码 + * @param scene 发送场景 {@link SysSmsSceneEnum} + * @return SysSmsCodeDO 手机验证码 + */ + SysSmsCodeDO checkCodeIsExpired(String mobile, String code, Integer scene); + } diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java index a5796c6fc..c7aa98f91 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java @@ -4,6 +4,7 @@ import cn.hutool.core.map.MapUtil; import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; import cn.iocoder.yudao.coreservice.modules.system.service.sms.SysSmsCoreService; import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; +import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthCheckCodeReqVO; import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthSendSmsReqVO; import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; import cn.iocoder.yudao.userserver.modules.system.dal.mysql.sms.SysSmsCodeMapper; @@ -11,13 +12,11 @@ import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsTemplateCodeConstants; import cn.iocoder.yudao.userserver.modules.system.framework.sms.SmsCodeProperties; import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.util.Date; -import java.util.concurrent.TimeUnit; import static cn.hutool.core.util.RandomUtil.randomInt; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -33,11 +32,6 @@ import static cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConst @Validated public class SysSmsCodeServiceImpl implements SysSmsCodeService { - /** - * 验证码 + 手机 在redis中存储的有效时间,单位:分钟 - */ - private static final Long CODE_TIME = 10L; - @Resource private SmsCodeProperties smsCodeProperties; @@ -50,9 +44,6 @@ public class SysSmsCodeServiceImpl implements SysSmsCodeService { @Resource private SysSmsCoreService smsCoreService; - @Resource - private StringRedisTemplate stringRedisTemplate; - @Override public void sendSmsCode(String mobile, Integer scene, String createIp) { // 创建验证码 @@ -61,12 +52,6 @@ public class SysSmsCodeServiceImpl implements SysSmsCodeService { // TODO @宋天:这里可以拓展下 SysSmsSceneEnum,支持设置对应的短信模板编号(不同场景的短信文案是不同的)、是否要校验手机号已经注册。这样 Controller 就可以收口成一个接口了。相当于说,不同场景,不同策略 smsCoreService.sendSingleSmsToMember(mobile, null, SysSmsTemplateCodeConstants.USER_SMS_LOGIN, MapUtil.of("code", code)); - - // 存储手机号与验证码到redis,用于标记 - // TODO @宋天:SysSmsCodeDO 表应该足够,无需增加额外的 redis 存储哇 - // TODO @宋天:Redis 相关的操作,不要散落到业务层,而是写一个它对应的 RedisDAO。这样,实现业务与技术的解耦 - // TODO @宋天:直接使用 code 作为 key,会存在 2 个问题:1)code 可能会冲突,多个手机号之间;2)缺少前缀。例如说 sms_code_${code} - stringRedisTemplate.opsForValue().set(code,mobile,CODE_TIME, TimeUnit.MINUTES); } @Override @@ -83,7 +68,7 @@ public class SysSmsCodeServiceImpl implements SysSmsCodeService { private String createSmsCode(String mobile, Integer scene, String ip) { // 校验是否可以发送验证码,不用筛选场景 - SysSmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile, null); + SysSmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile, null,null); if (lastSmsCode != null) { if (lastSmsCode.getTodayIndex() >= smsCodeProperties.getSendMaximumQuantityPerDay()) { // 超过当天发送的上限。 throw exception(USER_SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY); @@ -108,7 +93,7 @@ public class SysSmsCodeServiceImpl implements SysSmsCodeService { @Override public void useSmsCode(String mobile, Integer scene, String code, String usedIp) { // 校验验证码 - SysSmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile, scene); + SysSmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile, null,scene); if (lastSmsCode == null) { // 若验证码不存在,抛出异常 throw exception(USER_SMS_CODE_NOT_FOUND); } @@ -138,4 +123,21 @@ public class SysSmsCodeServiceImpl implements SysSmsCodeService { this.sendSmsCode(user.getMobile(),SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene(), getClientIP()); } + @Override + public SysSmsCodeDO checkCodeIsExpired(String mobile, String code, Integer scene) { + SysSmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile, code, scene); + + // 检测验证码是否存在 + if (lastSmsCode == null){ + throw exception(USER_SMS_CODE_EXPIRED); + } + + // 检测验证码是否过期 + if (System.currentTimeMillis() - lastSmsCode.getCreateTime().getTime() + >= smsCodeProperties.getExpireTimes().toMillis()) { + throw exception(USER_SMS_CODE_EXPIRED); + } + return lastSmsCode; + } + } diff --git a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/member/controller/SysUserProfileControllerTest.java b/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/member/controller/SysUserProfileControllerTest.java deleted file mode 100644 index 3f32cc82c..000000000 --- a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/member/controller/SysUserProfileControllerTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.member.controller; - -import cn.iocoder.yudao.userserver.modules.member.controller.user.SysUserProfileController; -import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; -import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; -import org.junit.Before; -import org.junit.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.result.MockMvcResultHandlers; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; - - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -/** - * {@link SysUserProfileController} 的单元测试类 - * - * @author 宋天 - */ -// TODO @宋天:controller 的单测可以不写哈,因为收益太低了。未来我们做 qa 自动化测试 -public class SysUserProfileControllerTest { - - private MockMvc mockMvc; - - @InjectMocks - private SysUserProfileController sysUserProfileController; - - @Mock - private MbrUserService userService; - - @Mock - private SysSmsCodeService smsCodeService; - - @Before // TODO @宋天:使用 junit5 哈 - public void setup() { - // 初始化 - MockitoAnnotations.openMocks(this); - - // 构建mvc环境 - mockMvc = MockMvcBuilders.standaloneSetup(sysUserProfileController).build(); - } - - @Test - public void testUpdateMobile_success() throws Exception { - //模拟接口调用 - this.mockMvc.perform(post("/system/user/profile/update-mobile") - .contentType(MediaType.APPLICATION_JSON_VALUE) - .content("{\"mobile\":\"15819844280\",\"code\":\"123456\"}}")) - .andExpect(status().isOk()) - .andDo(MockMvcResultHandlers.print()); -// TODO @宋天:方法的结尾,不用空行哈 - } - - -} diff --git a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/system/controller/SysAuthControllerTest.java b/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/system/controller/SysAuthControllerTest.java deleted file mode 100644 index 599ebaab6..000000000 --- a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/system/controller/SysAuthControllerTest.java +++ /dev/null @@ -1,75 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.controller; - -import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialService; -import cn.iocoder.yudao.userserver.modules.system.controller.auth.SysAuthController; -import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService; -import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; -import org.junit.Before; -import org.junit.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.result.MockMvcResultHandlers; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; - -import static org.springframework.http.HttpHeaders.AUTHORIZATION; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -/** - * {@link SysAuthController} 的单元测试类 - * - * @author 宋天 - */ -public class SysAuthControllerTest { - - private MockMvc mockMvc; - - @InjectMocks - private SysAuthController sysAuthController; - - @Mock - private SysAuthService authService; - @Mock - private SysSmsCodeService smsCodeService; - @Mock - private SysSocialService socialService; - - - @Before - public void setup() { - // 初始化 - MockitoAnnotations.openMocks(this); - - // 构建mvc环境 - mockMvc = MockMvcBuilders.standaloneSetup(sysAuthController).build(); - } - - @Test - public void testResetPassword_success() throws Exception { - //模拟接口调用 - this.mockMvc.perform(post("/reset-password") - .contentType(MediaType.APPLICATION_JSON) - .content("{\"password\":\"1123\",\"code\":\"123456\"}}")) - .andExpect(status().isOk()) - .andDo(MockMvcResultHandlers.print()); - - } - - @Test - public void testUpdatePassword_success() throws Exception { - //模拟接口调用 - this.mockMvc.perform(post("/update-password") - .contentType(MediaType.APPLICATION_JSON) - .content("{\"password\":\"1123\",\"code\":\"123456\",\"oldPassword\":\"1123\"}}")) - .andExpect(status().isOk()) - .andDo(MockMvcResultHandlers.print()); - - } - - - -} From 21fbe91e39f029174377699110d149d1d2e684c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=8B=E5=A4=A9?= <2982176321@qq.com> Date: Sat, 25 Dec 2021 00:05:21 +0800 Subject: [PATCH 2/4] =?UTF-8?q?update=20=E7=94=A8=E6=88=B7=E4=B8=AD?= =?UTF-8?q?=E5=BF=83=E5=AF=86=E7=A0=81=E6=93=8D=E4=BD=9C=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-local.yaml | 14 ++++---- .../service/user/impl/MbrUserServiceImpl.java | 27 ++++++-------- .../system/enums/SysErrorCodeConstants.java | 2 +- .../system/service/sms/SysSmsCodeService.java | 22 ++++++------ .../sms/impl/SysSmsCodeServiceImpl.java | 35 ++++++++----------- .../service/MbrUserServiceImplTest.java | 28 ++++++++------- .../system/service/SysAuthServiceTest.java | 13 +++---- 7 files changed, 64 insertions(+), 77 deletions(-) diff --git a/yudao-admin-server/src/main/resources/application-local.yaml b/yudao-admin-server/src/main/resources/application-local.yaml index 54d5447dc..89d1f357d 100644 --- a/yudao-admin-server/src/main/resources/application-local.yaml +++ b/yudao-admin-server/src/main/resources/application-local.yaml @@ -44,16 +44,16 @@ spring: datasource: master: name: ruoyi-vue-pro - url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT - driver-class-name: com.mysql.jdbc.Driver - username: root - password: 123456 - slave: # 模拟从库,可根据自己需要修改 - name: ruoyi-vue-pro - url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT + url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT driver-class-name: com.mysql.jdbc.Driver username: root password: 123456 +# slave: # 模拟从库,可根据自己需要修改 +# name: ruoyi-vue-pro +# url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT +# driver-class-name: com.mysql.jdbc.Driver +# username: root +# password: 123456 activiti: 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 d31ed9ee6..ee7690699 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 @@ -4,20 +4,20 @@ import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.IdUtil; import cn.iocoder.yudao.coreservice.modules.infra.service.file.InfFileCoreService; import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfoRespVO; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfoRespVO; import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserUpdateMobileReqVO; import cn.iocoder.yudao.userserver.modules.member.convert.user.UserProfileConvert; 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.system.dal.dataobject.sms.SysSmsCodeDO; 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.sms.SysSmsCodeService; import com.google.common.annotations.VisibleForTesting; import lombok.extern.slf4j.Slf4j; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import javax.validation.Valid; @@ -28,7 +28,6 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; import static cn.iocoder.yudao.userserver.modules.member.enums.MbrErrorCodeConstants.USER_NOT_EXISTS; import static cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConstants.USER_SMS_CODE_IS_UNUSED; -import static cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConstants.USER_SMS_CODE_NOT_CORRECT; /** * User Service 实现类 @@ -49,9 +48,6 @@ public class MbrUserServiceImpl implements MbrUserService { @Resource private PasswordEncoder passwordEncoder; - @Resource - private SysAuthService sysAuthService; - @Resource private SysSmsCodeService smsCodeService; @@ -130,24 +126,23 @@ public class MbrUserServiceImpl implements MbrUserService { } @Override + @Transactional(rollbackFor = Exception.class) public void updateMobile(Long userId, MbrUserUpdateMobileReqVO reqVO) { // 检测用户是否存在 checkUserExists(userId); - // 校验验证码,并标记为已使用 - smsCodeService.useSmsCode(reqVO.getMobile(), SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene(), reqVO.getCode(),getClientIP()); - // 检测新手机和旧手机的验证码是否在30分钟内 - SysSmsCodeDO smsOldCodeDO = smsCodeService.checkCodeIsExpired(reqVO.getOldMobile(), reqVO.getOldCode(), SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene()); - SysSmsCodeDO smsNewCodeDO = smsCodeService.checkCodeIsExpired(reqVO.getMobile(), reqVO.getCode(), SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene()); - - // 判断新旧code是否未被使用,如果是,抛出异常 - if (Boolean.FALSE.equals(smsOldCodeDO.getUsed()) || Boolean.FALSE.equals(smsNewCodeDO.getUsed())){ + // 校验旧手机和旧验证码 + SysSmsCodeDO sysSmsCodeDO = smsCodeService.checkCodeIsExpired(reqVO.getOldMobile(), reqVO.getOldCode(), SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene()); + // 判断旧code是否未被使用,如果是,抛出异常 + if (Boolean.FALSE.equals(sysSmsCodeDO.getUsed())){ throw exception(USER_SMS_CODE_IS_UNUSED); } + // 使用新验证码 + smsCodeService.useSmsCode(reqVO.getMobile(), SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene(), reqVO.getCode(),getClientIP()); + // 更新用户手机 - MbrUserDO userDO = MbrUserDO.builder().build(); - userDO.setMobile(reqVO.getMobile()); + MbrUserDO userDO = MbrUserDO.builder().id(userId).mobile(reqVO.getMobile()).build(); userMapper.updateById(userDO); } 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 c37dca9b0..05ae0ed3b 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 @@ -24,7 +24,7 @@ public interface SysErrorCodeConstants { ErrorCode USER_SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY = new ErrorCode(1005001004, "超过每日短信发送数量"); ErrorCode USER_SMS_CODE_SEND_TOO_FAST = new ErrorCode(1005001005, "短信发送过于频率"); ErrorCode USER_SMS_CODE_IS_EXISTS = new ErrorCode(1005001006, "手机号已被使用"); - ErrorCode USER_SMS_CODE_IS_UNUSED = new ErrorCode(1005001006, "手机号未被使用"); + ErrorCode USER_SMS_CODE_IS_UNUSED = new ErrorCode(1005001006, "验证码未被使用"); // ========== 用户模块 1005002000 ========== ErrorCode USER_NOT_EXISTS = new ErrorCode(1005002001, "用户不存在"); diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java index 160527d35..8a052c76d 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java @@ -2,9 +2,7 @@ package cn.iocoder.yudao.userserver.modules.system.service.sms; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.validation.Mobile; -import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthCheckCodeReqVO; import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthSendSmsReqVO; -import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthSmsLoginReqVO; import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; @@ -18,14 +16,15 @@ public interface SysSmsCodeService { /** * 创建短信验证码,并进行发送 * - * @param mobile 手机号 - * @param scene 发送场景 {@link SysSmsSceneEnum} + * @param mobile 手机号 + * @param scene 发送场景 {@link SysSmsSceneEnum} * @param createIp 发送 IP */ void sendSmsCode(@Mobile String mobile, Integer scene, String createIp); /** * 发送短信验证码,并检测手机号是否已被注册 + * * @param reqVO 请求实体 */ void sendSmsNewCode(SysAuthSendSmsReqVO reqVO); @@ -36,25 +35,26 @@ public interface SysSmsCodeService { * 如果错误,则抛出 {@link ServiceException} 异常 * * @param mobile 手机号 - * @param scene 发送场景 - * @param code 验证码 + * @param scene 发送场景 + * @param code 验证码 * @param usedIp 使用 IP */ void useSmsCode(@Mobile String mobile, Integer scene, String code, String usedIp); /** * 根据用户id发送验证码 + * * @param userId 用户id */ void sendSmsCodeLogin(Long userId); + /** - * 检测手机验证码是否有效 - * @param mobile 手机号 + * 检查验证码是否有效 + * @param mobile 手机 * @param code 验证码 - * @param scene 发送场景 {@link SysSmsSceneEnum} - * @return SysSmsCodeDO 手机验证码 + * @param scene 使用场景 + * @return 验证码记录 */ SysSmsCodeDO checkCodeIsExpired(String mobile, String code, Integer scene); - } diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java index c7aa98f91..d0fd64dfe 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java @@ -4,7 +4,6 @@ import cn.hutool.core.map.MapUtil; import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; import cn.iocoder.yudao.coreservice.modules.system.service.sms.SysSmsCoreService; import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; -import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthCheckCodeReqVO; import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthSendSmsReqVO; import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; import cn.iocoder.yudao.userserver.modules.system.dal.mysql.sms.SysSmsCodeMapper; @@ -92,21 +91,14 @@ public class SysSmsCodeServiceImpl implements SysSmsCodeService { @Override public void useSmsCode(String mobile, Integer scene, String code, String usedIp) { - // 校验验证码 - SysSmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile, null,scene); - if (lastSmsCode == null) { // 若验证码不存在,抛出异常 - throw exception(USER_SMS_CODE_NOT_FOUND); - } - if (System.currentTimeMillis() - lastSmsCode.getCreateTime().getTime() - >= smsCodeProperties.getExpireTimes().toMillis()) { // 验证码已过期 - throw exception(USER_SMS_CODE_EXPIRED); - } - if (lastSmsCode.getUsed()) { // 验证码已使用 + + // 检测验证码是否有效 + SysSmsCodeDO lastSmsCode = this.checkCodeIsExpired(mobile, code, scene); + + // 判断验证码是否已被使用 + if (Boolean.TRUE.equals(lastSmsCode.getUsed())) { throw exception(USER_SMS_CODE_USED); } - if (!lastSmsCode.getCode().equals(code)) { - throw exception(USER_SMS_CODE_NOT_CORRECT); - } // 使用验证码 smsCodeMapper.updateById(SysSmsCodeDO.builder().id(lastSmsCode.getId()) @@ -125,19 +117,20 @@ public class SysSmsCodeServiceImpl implements SysSmsCodeService { @Override public SysSmsCodeDO checkCodeIsExpired(String mobile, String code, Integer scene) { - SysSmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile, code, scene); + // 校验验证码 + SysSmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile,code,scene); - // 检测验证码是否存在 - if (lastSmsCode == null){ - throw exception(USER_SMS_CODE_EXPIRED); + // 若验证码不存在,抛出异常 + if (lastSmsCode == null) { + throw exception(USER_SMS_CODE_NOT_FOUND); } - - // 检测验证码是否过期 if (System.currentTimeMillis() - lastSmsCode.getCreateTime().getTime() - >= smsCodeProperties.getExpireTimes().toMillis()) { + >= smsCodeProperties.getExpireTimes().toMillis()) { // 验证码已过期 throw exception(USER_SMS_CODE_EXPIRED); } + return lastSmsCode; + } } diff --git a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/member/service/MbrUserServiceImplTest.java b/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/member/service/MbrUserServiceImplTest.java index 05571ba2e..68f41643b 100644 --- a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/member/service/MbrUserServiceImplTest.java +++ b/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/member/service/MbrUserServiceImplTest.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.userserver.modules.member.service; +import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.coreservice.modules.infra.service.file.InfFileCoreService; import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; @@ -10,8 +11,7 @@ import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfo import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserUpdateMobileReqVO; import cn.iocoder.yudao.userserver.modules.member.dal.mysql.user.MbrUserMapper; import cn.iocoder.yudao.userserver.modules.member.service.user.impl.MbrUserServiceImpl; -import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthSendSmsReqVO; -import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; +import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; import cn.iocoder.yudao.userserver.modules.system.service.auth.impl.SysAuthServiceImpl; import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; import org.junit.jupiter.api.Test; @@ -27,6 +27,7 @@ import java.util.function.Consumer; import static cn.hutool.core.util.RandomUtil.*; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString; +import static cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.*; @@ -115,23 +116,24 @@ public class MbrUserServiceImplTest extends BaseDbAndRedisUnitTest { userDO.setMobile(oldMobile); userMapper.insert(userDO); - // 验证旧手机 - sysSmsCodeService.sendSmsCodeLogin(userDO.getId()); - // 验证旧手机验证码是否正确 - sysSmsCodeService.useSmsCode(oldMobile,SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene(),"123","1.1.1.1"); - // 验证新手机 - SysAuthSendSmsReqVO smsReqVO = new SysAuthSendSmsReqVO(); - smsReqVO.setMobile(oldMobile); - smsReqVO.setScene(SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene()); - sysSmsCodeService.sendSmsNewCode(smsReqVO); + // 旧手机和旧验证码 + SysSmsCodeDO codeDO = new SysSmsCodeDO(); + String oldCode = RandomUtil.randomString(4); + codeDO.setMobile(userDO.getMobile()); + codeDO.setCode(oldCode); + codeDO.setScene(CHANGE_MOBILE_BY_SMS.getScene()); + codeDO.setUsed(Boolean.FALSE); + when(sysSmsCodeService.checkCodeIsExpired(codeDO.getMobile(),codeDO.getCode(),codeDO.getScene())).thenReturn(codeDO); // 更新手机号 String newMobile = randomNumbers(11); - String code = randomNumbers(4); + String newCode = randomNumbers(4); MbrUserUpdateMobileReqVO reqVO = new MbrUserUpdateMobileReqVO(); reqVO.setMobile(newMobile); - reqVO.setCode(code); + reqVO.setCode(newCode); + reqVO.setOldMobile(oldMobile); + reqVO.setOldCode(oldCode); mbrUserService.updateMobile(userDO.getId(),reqVO); assertEquals(mbrUserService.getUser(userDO.getId()).getMobile(),newMobile); diff --git a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/system/service/SysAuthServiceTest.java b/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/system/service/SysAuthServiceTest.java index 83cf35be6..4c8b953c6 100644 --- a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/system/service/SysAuthServiceTest.java +++ b/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/system/service/SysAuthServiceTest.java @@ -23,7 +23,6 @@ import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.crypto.password.PasswordEncoder; import javax.annotation.Resource; -import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import static cn.hutool.core.util.RandomUtil.randomEle; @@ -99,17 +98,15 @@ public class SysAuthServiceTest extends BaseDbAndRedisUnitTest { // 随机验证码 String code = randomNumbers(4); - MbrAuthResetPasswordReqVO reqVO = MbrAuthResetPasswordReqVO.builder() - .password(password) - .code(code) - .build(); - // 放入code+手机号 - stringRedisTemplate.opsForValue().set(code,userDO.getMobile(),10, TimeUnit.MINUTES); - // mock when(passwordEncoder.encode(password)).thenReturn(password); // 更新用户密码 + MbrAuthResetPasswordReqVO reqVO = new MbrAuthResetPasswordReqVO(); + reqVO.setMobile(userDO.getMobile()); + reqVO.setPassword(password); + reqVO.setCode(code); + authService.resetPassword(reqVO); assertEquals(mbrUserMapper.selectById(userDO.getId()).getPassword(),password); } From 671c41bf825f21b7abc6dc8c1051cb0f2432c878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=8B=E5=A4=A9?= <2982176321@qq.com> Date: Sun, 26 Dec 2021 12:51:49 +0800 Subject: [PATCH 3/4] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8Dyml=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E8=AF=AF=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-local.yaml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/yudao-admin-server/src/main/resources/application-local.yaml b/yudao-admin-server/src/main/resources/application-local.yaml index 89d1f357d..6a7fa17a5 100644 --- a/yudao-admin-server/src/main/resources/application-local.yaml +++ b/yudao-admin-server/src/main/resources/application-local.yaml @@ -44,17 +44,16 @@ spring: datasource: master: name: ruoyi-vue-pro - url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT + url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT + driver-class-name: com.mysql.jdbc.Driver + username: root + password: 123456 + slave: # 模拟从库,可根据自己需要修改 + name: ruoyi-vue-pro + url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT driver-class-name: com.mysql.jdbc.Driver username: root password: 123456 -# slave: # 模拟从库,可根据自己需要修改 -# name: ruoyi-vue-pro -# url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT -# driver-class-name: com.mysql.jdbc.Driver -# username: root -# password: 123456 - activiti: #1.false:默认值,activiti启动时,对比数据库表中保存的版本,如果不匹配。将抛出异常 From df141f2982854aa8fb220cdc9958562ce0233112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=8B=E5=A4=A9?= <2982176321@qq.com> Date: Sun, 26 Dec 2021 15:21:14 +0800 Subject: [PATCH 4/4] =?UTF-8?q?update=20=E5=8F=91=E9=80=81=E7=9F=AD?= =?UTF-8?q?=E4=BF=A1=20=E6=8B=93=E5=B1=95=E8=AE=BE=E7=BD=AE=E5=AF=B9?= =?UTF-8?q?=E5=BA=94=E6=A8=A1=E6=9D=BF=E7=BC=96=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/auth/SysAuthController.java | 12 +------- .../system/enums/sms/SysSmsSceneEnum.java | 28 ++++++++++++++++--- .../sms/SysSmsTemplateCodeConstants.java | 10 +++++++ .../system/service/sms/SysSmsCodeService.java | 8 ------ .../sms/impl/SysSmsCodeServiceImpl.java | 21 ++++++++------ 5 files changed, 48 insertions(+), 31 deletions(-) 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 5d50714ce..2c0d49307 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 @@ -5,10 +5,8 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.*; -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.sms.SysSmsCodeService; -import com.alibaba.fastjson.JSON; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; @@ -18,7 +16,6 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -57,19 +54,12 @@ public class SysAuthController { } @PostMapping("/send-sms-code") - @ApiOperation(value = "发送手机验证码",notes = "不检测该手机号是否已被注册") + @ApiOperation(value = "发送手机验证码") public CommonResult sendSmsCode(@RequestBody @Valid SysAuthSendSmsReqVO reqVO) { smsCodeService.sendSmsCode(reqVO.getMobile(), reqVO.getScene(), getClientIP()); return success(true); } - @PostMapping("/send-sms-new-code") - @ApiOperation(value = "发送手机验证码",notes = "检测该手机号是否已被注册,用于修改手机时使用") - public CommonResult sendSmsNewCode(@RequestBody @Valid SysAuthSendSmsReqVO reqVO) { - smsCodeService.sendSmsNewCode(reqVO); - return success(true); - } - @GetMapping("/send-sms-code-login") @ApiOperation(value = "向已登录用户发送验证码",notes = "修改手机时验证原手机号使用") public CommonResult sendSmsCodeLogin() { diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsSceneEnum.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsSceneEnum.java index c2156d218..9cea09230 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsSceneEnum.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsSceneEnum.java @@ -15,15 +15,26 @@ import java.util.Arrays; @AllArgsConstructor public enum SysSmsSceneEnum implements IntArrayValuable { - LOGIN_BY_SMS(1, "手机号登陆"), - CHANGE_MOBILE_BY_SMS(2, "更换手机号"), - FORGET_MOBILE_BY_SMS(3, "忘记密码"), - CHECK_CODE_BY_SMS(4, "审核验证码"), + LOGIN_BY_SMS(1,SysSmsTemplateCodeConstants.USER_SMS_LOGIN, "手机号登陆"), + CHANGE_MOBILE_BY_SMS(2,SysSmsTemplateCodeConstants.USER_SMS_UPDATE_MOBILE, "更换手机号"), + FORGET_MOBILE_BY_SMS(3,SysSmsTemplateCodeConstants.USER_SMS_RESET_PASSWORD, "忘记密码"), ; public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SysSmsSceneEnum::getScene).toArray(); + /** + * 验证那场景编号 + */ private final Integer scene; + + /** + * 模版编码 + */ + private final String code; + + /** + * 描述 + */ private final String name; @Override @@ -31,4 +42,13 @@ public enum SysSmsSceneEnum implements IntArrayValuable { return ARRAYS; } + public static String getCodeByScene(Integer scene){ + for (SysSmsSceneEnum value : values()) { + if (value.getScene().equals(scene)){ + return value.getCode(); + } + } + return null; + } + } diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsTemplateCodeConstants.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsTemplateCodeConstants.java index 5529a0741..8a83f75f2 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsTemplateCodeConstants.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsTemplateCodeConstants.java @@ -12,4 +12,14 @@ public interface SysSmsTemplateCodeConstants { */ String USER_SMS_LOGIN = "user-sms-login"; + /** + * 用户忘记密码 + */ + String USER_SMS_RESET_PASSWORD = "user-sms-reset-password"; + + /** + * 用户更新手机号 + */ + String USER_SMS_UPDATE_MOBILE = "user-sms-update-mobile"; + } diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java index 8a052c76d..281f18ce6 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.userserver.modules.system.service.sms; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.validation.Mobile; -import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthSendSmsReqVO; import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; @@ -22,13 +21,6 @@ public interface SysSmsCodeService { */ void sendSmsCode(@Mobile String mobile, Integer scene, String createIp); - /** - * 发送短信验证码,并检测手机号是否已被注册 - * - * @param reqVO 请求实体 - */ - void sendSmsNewCode(SysAuthSendSmsReqVO reqVO); - /** * 验证短信验证码,并进行使用 * 如果正确,则将验证码标记成已使用 diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java index d0fd64dfe..80fc15a8a 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java @@ -4,11 +4,9 @@ import cn.hutool.core.map.MapUtil; import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; import cn.iocoder.yudao.coreservice.modules.system.service.sms.SysSmsCoreService; import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; -import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthSendSmsReqVO; import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; import cn.iocoder.yudao.userserver.modules.system.dal.mysql.sms.SysSmsCodeMapper; import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; -import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsTemplateCodeConstants; import cn.iocoder.yudao.userserver.modules.system.framework.sms.SmsCodeProperties; import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; import org.springframework.stereotype.Service; @@ -47,22 +45,29 @@ public class SysSmsCodeServiceImpl implements SysSmsCodeService { public void sendSmsCode(String mobile, Integer scene, String createIp) { // 创建验证码 String code = this.createSmsCode(mobile, scene, createIp); + + // 获取发送模板 + String codeTemplate = SysSmsSceneEnum.getCodeByScene(scene); + + // 如果是更换手机号发送验证码,则需要检测手机号是否被注册 + if (SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene().equals(scene)){ + this.checkMobileIsRegister(mobile,scene); + } + // 发送验证码 - // TODO @宋天:这里可以拓展下 SysSmsSceneEnum,支持设置对应的短信模板编号(不同场景的短信文案是不同的)、是否要校验手机号已经注册。这样 Controller 就可以收口成一个接口了。相当于说,不同场景,不同策略 - smsCoreService.sendSingleSmsToMember(mobile, null, SysSmsTemplateCodeConstants.USER_SMS_LOGIN, + smsCoreService.sendSingleSmsToMember(mobile, null, codeTemplate, MapUtil.of("code", code)); } - @Override - public void sendSmsNewCode(SysAuthSendSmsReqVO reqVO) { + public void checkMobileIsRegister(String mobile, Integer scene) { // 检测手机号是否已被使用 - MbrUserDO userByMobile = mbrUserService.getUserByMobile(reqVO.getMobile()); + MbrUserDO userByMobile = mbrUserService.getUserByMobile(mobile); if (userByMobile != null){ throw exception(USER_SMS_CODE_IS_EXISTS); } // 发送短信 - this.sendSmsCode(reqVO.getMobile(),reqVO.getScene(),getClientIP()); + this.sendSmsCode(mobile,scene,getClientIP()); } private String createSmsCode(String mobile, Integer scene, String ip) {