Commit 95254341a1169fb9af29ad5a3576cdef7721a23f

Authored by YunaiV
1 parent 5d4a7ffa

1. 会员用户的找回密码 API 的优化

Showing 11 changed files with 57 additions and 54 deletions
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java
... ... @@ -11,7 +11,7 @@ public interface ErrorCodeConstants {
11 11  
12 12 // ========== 用户相关 1004001000============
13 13 ErrorCode USER_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在");
14   - ErrorCode USER_PASSWORD_FAILED = new ErrorCode(1004001001, "密码校验失败");
  14 + ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1004001001, "手机号未注册用户");
15 15 ErrorCode USER_MOBILE_USED = new ErrorCode(1004001002, "修改手机失败,该手机号({})已经被使用");
16 16  
17 17 // ========== AUTH 模块 1004003000 ==========
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java
... ... @@ -4,7 +4,6 @@ import cn.hutool.core.util.StrUtil;
4 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 5 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
6 6 import cn.iocoder.yudao.framework.security.config.SecurityProperties;
7   -import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
8 7 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
9 8 import cn.iocoder.yudao.module.member.controller.app.auth.vo.*;
10 9 import cn.iocoder.yudao.module.member.service.auth.MemberAuthService;
... ... @@ -84,14 +83,6 @@ public class AppAuthController {
84 83 return success(true);
85 84 }
86 85  
87   - @PostMapping("/reset-password")
88   - @Operation(summary = "重置密码", description = "用户忘记密码时使用")
89   - @PreAuthenticated
90   - public CommonResult<Boolean> resetPassword(@RequestBody @Valid AppAuthResetPasswordReqVO reqVO) {
91   - authService.resetPassword(reqVO);
92   - return success(true);
93   - }
94   -
95 86 // ========== 社交登录相关 ==========
96 87  
97 88 @GetMapping("/social-auth-redirect")
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java
... ... @@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.member.controller.app.user;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
5   -import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserInfoRespVO;
6   -import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserUpdatePasswordReqVO;
7   -import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserUpdateReqVO;
8   -import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserUpdateMobileReqVO;
  5 +import cn.iocoder.yudao.module.member.controller.app.user.vo.*;
9 6 import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert;
10 7 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
11 8 import cn.iocoder.yudao.module.member.service.user.MemberUserService;
... ... @@ -63,5 +60,12 @@ public class AppMemberUserController {
63 60 return success(true);
64 61 }
65 62  
  63 + @PutMapping("/reset-password")
  64 + @Operation(summary = "重置密码", description = "用户忘记密码时使用")
  65 + public CommonResult<Boolean> resetPassword(@RequestBody @Valid AppMemberUserResetPasswordReqVO reqVO) {
  66 + userService.resetUserPassword(reqVO);
  67 + return success(true);
  68 + }
  69 +
66 70 }
67 71  
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java renamed to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppMemberUserResetPasswordReqVO.java
1   -package cn.iocoder.yudao.module.member.controller.app.auth.vo;
  1 +package cn.iocoder.yudao.module.member.controller.app.user.vo;
2 2  
3 3 import cn.iocoder.yudao.framework.common.validation.Mobile;
4 4 import io.swagger.v3.oas.annotations.media.Schema;
... ... @@ -12,13 +12,12 @@ import javax.validation.constraints.NotBlank;
12 12 import javax.validation.constraints.NotEmpty;
13 13 import javax.validation.constraints.Pattern;
14 14  
15   -// TODO 芋艿:code review 相关逻辑
16 15 @Schema(description = "用户 APP - 重置密码 Request VO")
17 16 @Data
18 17 @NoArgsConstructor
19 18 @AllArgsConstructor
20 19 @Builder
21   -public class AppAuthResetPasswordReqVO {
  20 +public class AppMemberUserResetPasswordReqVO {
22 21  
23 22 @Schema(description = "新密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "buzhidao")
24 23 @NotEmpty(message = "新密码不能为空")
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java
... ... @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.member.convert.auth;
2 2  
3 3 import cn.iocoder.yudao.module.member.controller.app.auth.vo.*;
4 4 import cn.iocoder.yudao.module.member.controller.app.social.vo.AppSocialUserUnbindReqVO;
  5 +import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserResetPasswordReqVO;
5 6 import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenRespDTO;
6 7 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
7 8 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
... ... @@ -21,7 +22,7 @@ public interface AuthConvert {
21 22 SocialUserUnbindReqDTO convert(Long userId, Integer userType, AppSocialUserUnbindReqVO reqVO);
22 23  
23 24 SmsCodeSendReqDTO convert(AppAuthSmsSendReqVO reqVO);
24   - SmsCodeUseReqDTO convert(AppAuthResetPasswordReqVO reqVO, SmsSceneEnum scene, String usedIp);
  25 + SmsCodeUseReqDTO convert(AppMemberUserResetPasswordReqVO reqVO, SmsSceneEnum scene, String usedIp);
25 26 SmsCodeUseReqDTO convert(AppAuthSmsLoginReqVO reqVO, Integer scene, String usedIp);
26 27  
27 28 AppAuthLoginRespVO convert(OAuth2AccessTokenRespDTO bean);
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthService.java
... ... @@ -62,12 +62,6 @@ public interface MemberAuthService {
62 62 String getSocialAuthorizeUrl(Integer type, String redirectUri);
63 63  
64 64 /**
65   - * 忘记密码
66   - * @param userReqVO 用户请求实体类
67   - */
68   - void resetPassword(AppAuthResetPasswordReqVO userReqVO);
69   -
70   - /**
71 65 * 给用户发送短信验证码
72 66 *
73 67 * @param userId 用户编号
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java
... ... @@ -27,7 +27,6 @@ import cn.iocoder.yudao.module.system.enums.oauth2.OAuth2ClientConstants;
27 27 import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
28 28 import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
29 29 import lombok.extern.slf4j.Slf4j;
30   -import org.springframework.security.crypto.password.PasswordEncoder;
31 30 import org.springframework.stereotype.Service;
32 31 import org.springframework.transaction.annotation.Transactional;
33 32  
... ... @@ -62,8 +61,6 @@ public class MemberAuthServiceImpl implements MemberAuthService {
62 61 private WxMaService wxMaService;
63 62  
64 63 @Resource
65   - private PasswordEncoder passwordEncoder;
66   - @Resource
67 64 private MemberUserMapper userMapper;
68 65  
69 66 @Override
... ... @@ -209,28 +206,21 @@ public class MemberAuthServiceImpl implements MemberAuthService {
209 206 }
210 207  
211 208 @Override
212   - public void resetPassword(AppAuthResetPasswordReqVO reqVO) {
213   - // 检验用户是否存在
214   - MemberUserDO userDO = checkUserIfExists(reqVO.getMobile());
215   -
216   - // 使用验证码
217   - smsCodeApi.useSmsCode(AuthConvert.INSTANCE.convert(reqVO, SmsSceneEnum.MEMBER_FORGET_PASSWORD,
218   - getClientIP()));
219   -
220   - // 更新密码
221   - userMapper.updateById(MemberUserDO.builder().id(userDO.getId())
222   - .password(passwordEncoder.encode(reqVO.getPassword())).build());
223   - }
224   -
225   - @Override
226 209 public void sendSmsCode(Long userId, AppAuthSmsSendReqVO reqVO) {
227   - // 如果是修改手机场景,需要校验新手机号是否已经注册,说明不能使用该手机了
  210 + // 情况 1:如果是修改手机场景,需要校验新手机号是否已经注册,说明不能使用该手机了
228 211 if (Objects.equals(reqVO.getScene(), SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene())) {
229   - MemberUserDO user = userMapper.selectByMobile(reqVO.getMobile());
  212 + MemberUserDO user = userService.getUserByMobile(reqVO.getMobile());
230 213 if (user != null && !Objects.equals(user.getId(), userId)) {
231 214 throw exception(AUTH_MOBILE_USED);
232 215 }
233 216 }
  217 + // 情况 2:如果是重置密码场景,需要校验手机号是存在的
  218 + if (Objects.equals(reqVO.getScene(), SmsSceneEnum.MEMBER_RESET_PASSWORD.getScene())) {
  219 + MemberUserDO user= userService.getUserByMobile(reqVO.getMobile());
  220 + if (user == null) {
  221 + throw exception(USER_MOBILE_NOT_EXISTS);
  222 + }
  223 + }
234 224  
235 225 // 执行发送
236 226 smsCodeApi.sendSmsCode(AuthConvert.INSTANCE.convert(reqVO).setCreateIp(getClientIP()));
... ... @@ -248,14 +238,6 @@ public class MemberAuthServiceImpl implements MemberAuthService {
248 238 return AuthConvert.INSTANCE.convert(accessTokenDO);
249 239 }
250 240  
251   - public MemberUserDO checkUserIfExists(String mobile) {
252   - MemberUserDO user = userMapper.selectByMobile(mobile);
253   - if (user == null) {
254   - throw exception(USER_NOT_EXISTS);
255   - }
256   - return user;
257   - }
258   -
259 241 private void createLogoutLog(Long userId) {
260 242 LoginLogCreateReqDTO reqDTO = new LoginLogCreateReqDTO();
261 243 reqDTO.setLogType(LoginLogTypeEnum.LOGOUT_SELF.getType());
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java
... ... @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.common.validation.Mobile;
5 5 import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO;
6 6 import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
  7 +import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserResetPasswordReqVO;
7 8 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserUpdatePasswordReqVO;
8 9 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserUpdateReqVO;
9 10 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserUpdateMobileReqVO;
... ... @@ -95,6 +96,13 @@ public interface MemberUserService {
95 96 void updateUserPassword(Long userId, AppMemberUserUpdatePasswordReqVO reqVO);
96 97  
97 98 /**
  99 + * 【会员】忘记密码
  100 + *
  101 + * @param reqVO 请求信息
  102 + */
  103 + void resetUserPassword(AppMemberUserResetPasswordReqVO reqVO);
  104 +
  105 + /**
98 106 * 判断密码是否匹配
99 107 *
100 108 * @param rawPassword 未加密的密码
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java
... ... @@ -7,9 +7,11 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 7 import cn.iocoder.yudao.module.infra.api.file.FileApi;
8 8 import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO;
9 9 import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
  10 +import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserResetPasswordReqVO;
10 11 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserUpdatePasswordReqVO;
11 12 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserUpdateReqVO;
12 13 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserUpdateMobileReqVO;
  14 +import cn.iocoder.yudao.module.member.convert.auth.AuthConvert;
13 15 import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert;
14 16 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
15 17 import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
... ... @@ -142,6 +144,28 @@ public class MemberUserServiceImpl implements MemberUserService {
142 144 }
143 145  
144 146 @Override
  147 + public void resetUserPassword(AppMemberUserResetPasswordReqVO reqVO) {
  148 + // 检验用户是否存在
  149 + MemberUserDO user = validateUserExists(reqVO.getMobile());
  150 +
  151 + // 使用验证码
  152 + smsCodeApi.useSmsCode(AuthConvert.INSTANCE.convert(reqVO, SmsSceneEnum.MEMBER_RESET_PASSWORD,
  153 + getClientIP()));
  154 +
  155 + // 更新密码
  156 + memberUserMapper.updateById(MemberUserDO.builder().id(user.getId())
  157 + .password(passwordEncoder.encode(reqVO.getPassword())).build());
  158 + }
  159 +
  160 + private MemberUserDO validateUserExists(String mobile) {
  161 + MemberUserDO user = memberUserMapper.selectByMobile(mobile);
  162 + if (user == null) {
  163 + throw exception(USER_MOBILE_NOT_EXISTS);
  164 + }
  165 + return user;
  166 + }
  167 +
  168 + @Override
145 169 public boolean isPasswordMatch(String rawPassword, String encodedPassword) {
146 170 return passwordEncoder.matches(rawPassword, encodedPassword);
147 171 }
... ...
yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceTest.java
... ... @@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
5 5 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
6 6 import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
7 7 import cn.iocoder.yudao.framework.test.core.ut.BaseDbAndRedisUnitTest;
8   -import cn.iocoder.yudao.module.member.controller.app.auth.vo.AppAuthResetPasswordReqVO;
  8 +import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserResetPasswordReqVO;
9 9 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserUpdatePasswordReqVO;
10 10 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
11 11 import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
... ... @@ -101,7 +101,7 @@ public class MemberAuthServiceTest extends BaseDbAndRedisUnitTest {
101 101 when(passwordEncoder.encode(password)).thenReturn(password);
102 102  
103 103 // 更新用户密码
104   - AppAuthResetPasswordReqVO reqVO = new AppAuthResetPasswordReqVO();
  104 + AppMemberUserResetPasswordReqVO reqVO = new AppMemberUserResetPasswordReqVO();
105 105 reqVO.setMobile(userDO.getMobile());
106 106 reqVO.setPassword(password);
107 107 reqVO.setCode(code);
... ...
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsSceneEnum.java
... ... @@ -19,7 +19,7 @@ public enum SmsSceneEnum implements IntArrayValuable {
19 19 MEMBER_LOGIN(1, "user-sms-login", "会员用户 - 手机号登陆"),
20 20 MEMBER_UPDATE_MOBILE(2, "user-update-mobile", "会员用户 - 修改手机"),
21 21 MEMBER_UPDATE_PASSWORD(3, "user-update-mobile", "会员用户 - 修改密码"),
22   - MEMBER_FORGET_PASSWORD(4, "user-forget-password", "会员用户 - 忘记密码"),
  22 + MEMBER_RESET_PASSWORD(4, "user-reset-password", "会员用户 - 忘记密码"),
23 23  
24 24 ADMIN_MEMBER_LOGIN(21, "admin-sms-login", "后台用户 - 手机号登录");
25 25  
... ...