From d6c5bebf361d3d192eac3f5973596765a834b5ee Mon Sep 17 00:00:00 2001 From: khalil Date: Fri, 14 Mar 2025 16:43:05 +0800 Subject: [PATCH] =?UTF-8?q?=E9=82=AE=E7=AE=B1-=E9=87=8D=E7=BD=AE=E5=AF=86?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/service/account/AccountService.java | 23 ++----- .../accompany/common/utils/CommonUtil.java | 14 +++++ .../accompany/email/service/EmailService.java | 10 +++ .../com/accompany/sms/service/SmsService.java | 11 ++++ .../service/account/AccountManageService.java | 61 +++++++++++++++---- .../oauth2/controller/PwdController.java | 32 +++++++++- 6 files changed, 120 insertions(+), 31 deletions(-) diff --git a/accompany-base/accompany-basic/accompany-basic-service/src/main/java/com/accompany/core/service/account/AccountService.java b/accompany-base/accompany-basic/accompany-basic-service/src/main/java/com/accompany/core/service/account/AccountService.java index 15b528947..718b9a00a 100644 --- a/accompany-base/accompany-basic/accompany-basic-service/src/main/java/com/accompany/core/service/account/AccountService.java +++ b/accompany-base/accompany-basic/accompany-basic-service/src/main/java/com/accompany/core/service/account/AccountService.java @@ -109,6 +109,12 @@ public class AccountService extends ServiceImpl { return count(wrapper); } + public long countByEmail(String email) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.lambda().eq(Account::getEmail, email); + return count(wrapper); + } + /** * 更改账户萌声号 * @@ -214,23 +220,6 @@ public class AccountService extends ServiceImpl { return count(wrapper); } - public boolean verifySmsCodeByCache(String mobile, String code, Long uid) { - String codeStr = jedisService.get(getSmsCodeKey(mobile, uid)); - if (!StringUtils.isEmpty(codeStr) && codeStr.equals(code)) { - return true; - } else { - return false; - } - } - - private String getSmsCodeKey(String mobile, Long uid) { - return RedisKey.sms.getKey(mobile); - } - - public void delSmsCodeCache(String mobile, Long uid) { - jedisService.del(getSmsCodeKey(mobile, uid)); - } - public void delNickPasswordCache(Long erbanNo) { String key = RedisKey.user_erban_no_uid.getKey(erbanNo.toString()); jedisService.del(key); diff --git a/accompany-base/accompany-core/src/main/java/com/accompany/common/utils/CommonUtil.java b/accompany-base/accompany-core/src/main/java/com/accompany/common/utils/CommonUtil.java index ce8667483..a15222371 100644 --- a/accompany-base/accompany-core/src/main/java/com/accompany/common/utils/CommonUtil.java +++ b/accompany-base/accompany-core/src/main/java/com/accompany/common/utils/CommonUtil.java @@ -295,6 +295,20 @@ public class CommonUtil { } } + /** + * 確認手機號格式是否正確 + * + * @param email + * @return + */ + public static boolean checkEmailFormat(String email) { + if (checkNumberOnly(email)) { + //log.error("checkPhoneFormat, not number {} {}", phone, areaCode); + return false; + } + return true; + } + private static boolean checkValidPhone(String phone, String phoneRegex) { if (StringUtils.isBlank(phone)) { return false; diff --git a/accompany-base/accompany-email/accompany-email-service/src/main/java/com/accompany/email/service/EmailService.java b/accompany-base/accompany-email/accompany-email-service/src/main/java/com/accompany/email/service/EmailService.java index e94c80304..3fccbb091 100644 --- a/accompany-base/accompany-email/accompany-email-service/src/main/java/com/accompany/email/service/EmailService.java +++ b/accompany-base/accompany-email/accompany-email-service/src/main/java/com/accompany/email/service/EmailService.java @@ -113,5 +113,15 @@ public class EmailService extends BaseService { } + public boolean verifyCodeByCache(String email, String code) { + String codeKey = RedisKey.email_code.getKey(email); + RBucket codeBucket = redissonClient.getBucket(codeKey); + return code.equals(codeBucket.get()); + } + public void delCodeCache(String email) { + String codeKey = RedisKey.email_code.getKey(email); + RBucket codeBucket = redissonClient.getBucket(codeKey); + codeBucket.delete(); + } } diff --git a/accompany-base/accompany-sms/accompany-sms-service/src/main/java/com/accompany/sms/service/SmsService.java b/accompany-base/accompany-sms/accompany-sms-service/src/main/java/com/accompany/sms/service/SmsService.java index 795b9d91f..633011e2d 100644 --- a/accompany-base/accompany-sms/accompany-sms-service/src/main/java/com/accompany/sms/service/SmsService.java +++ b/accompany-base/accompany-sms/accompany-sms-service/src/main/java/com/accompany/sms/service/SmsService.java @@ -126,6 +126,17 @@ public class SmsService extends BaseService { return false; } + public boolean verifySmsCodeByCache(String phone, String code) { + String cacheKey = getSmsKey(phone); + String codeStr = jedisService.get(cacheKey); + return !StringUtils.isBlank(codeStr) && codeStr.equals(code); + } + + public void delSmsCodeCache(String phone) { + String cacheKey = getSmsKey(phone); + jedisService.del(cacheKey); + } + /** * 获取短信验证码的RedisKey * diff --git a/accompany-oauth2/accompany-oauth2-service/src/main/java/com/accompany/oauth2/service/account/AccountManageService.java b/accompany-oauth2/accompany-oauth2-service/src/main/java/com/accompany/oauth2/service/account/AccountManageService.java index adc13db95..3cec00c5e 100644 --- a/accompany-oauth2/accompany-oauth2-service/src/main/java/com/accompany/oauth2/service/account/AccountManageService.java +++ b/accompany-oauth2/accompany-oauth2-service/src/main/java/com/accompany/oauth2/service/account/AccountManageService.java @@ -24,11 +24,13 @@ import com.accompany.core.service.common.JedisService; import com.accompany.core.service.user.UserCancelRecordService; import com.accompany.core.service.user.UsersBaseService; import com.accompany.core.util.MD5; +import com.accompany.email.service.EmailService; import com.accompany.oauth2.constant.LoginTypeEnum; import com.accompany.oauth2.dto.DayIpMaxRegisterLimitConfig; import com.accompany.oauth2.dto.RepeatedDeviceIpRegisterLimitConfig; import com.accompany.oauth2.event.UserRegisterSuccessEvent; import com.accompany.oauth2.exception.CustomOAuth2Exception; +import com.accompany.sms.service.SmsService; import com.alibaba.fastjson.JSON; import com.google.gson.Gson; import lombok.SneakyThrows; @@ -50,33 +52,28 @@ public class AccountManageService { @Autowired private JedisService jedisService; - @Autowired private JedisLockService jedisLockService; - @Autowired private AccountMapper accountMapper; - @Autowired private NetEaseService netEaseService; - @Autowired private ErBanNoService erBanNoService; - @Autowired private AccountService accountService; - @Autowired private ApplicationContext applicationContext; - @Autowired private UsersBaseService usersBaseService; - @Autowired private UserCancelRecordService userCancelRecordService; - @Autowired private SysConfService sysConfService; + @Autowired + private SmsService smsService; + @Autowired + private EmailService emailService; protected Gson gson = new Gson(); @@ -380,16 +377,54 @@ public class AccountManageService { throw new ServiceException(BusiStatus.PHONE_BIND_ERROR); } - uid = account.getUid(); //检验验证码 - if (!accountService.verifySmsCodeByCache(phone, resetCode, uid)) { + if (!smsService.verifySmsCodeByCache(phone, resetCode)) { throw new ServiceException(BusiStatus.INVALID_IDENTIFYING_CODE); } accountService.resetAccountPwd(account.getUid(), password); //成功后删除验证码缓存 - accountService.delSmsCodeCache(phone, account.getUid()); - //accountService.delNickPasswordCache(account.getErbanNo()); + smsService.delSmsCodeCache(phone); + + // 删除用户信息缓存 + jedisService.hdel(RedisKey.user.getKey(), account.getUid().toString()); + jedisService.hdel(RedisKey.user_summary.getKey(), account.getUid().toString()); + accountService.delNickPasswordCache(account.getErbanNo()); + } + + /** + * 重置密码 + * 两个场景调用 => 客户端未登录 忘记密码, 此时uid 为 null 登录状态下忘记密码 uid有值 + * @param uid + * @param email + * @param password + * @param code + * @return 1:成功 2:重置码无效 3:用户不存在 + */ + public void resetPasswordByEmailCode(Long uid, String email, String password, String code) { + if (!CommonUtil.checkEmailFormat(email)){ + throw new ServiceException(BusiStatus.ACCOUNT_NOT_BIND_PHONE); + } + + long count = accountService.countByEmail(email); + if (count > 1L) { + throw new ServiceException(BusiStatus.PHONE_BIND_TOO_MANY_ACCOUNT); + } + + Account account = accountService.getAccountByEmail(email); + if (null == account || !account.getUid().equals(uid)) { + throw new ServiceException(BusiStatus.PHONE_BIND_ERROR); + } + + //检验验证码 + if (!emailService.verifyCodeByCache(email, code)) { + throw new ServiceException(BusiStatus.INVALID_IDENTIFYING_CODE); + } + + accountService.resetAccountPwd(account.getUid(), password); + //成功后删除验证码缓存 + emailService.delCodeCache(email); + // 删除用户信息缓存 jedisService.hdel(RedisKey.user.getKey(), account.getUid().toString()); jedisService.hdel(RedisKey.user_summary.getKey(), account.getUid().toString()); diff --git a/accompany-oauth2/accompany-oauth2-web/src/main/java/com/accompany/oauth2/controller/PwdController.java b/accompany-oauth2/accompany-oauth2-web/src/main/java/com/accompany/oauth2/controller/PwdController.java index e75b6ecb5..5a8baebc2 100644 --- a/accompany-oauth2/accompany-oauth2-web/src/main/java/com/accompany/oauth2/controller/PwdController.java +++ b/accompany-oauth2/accompany-oauth2-web/src/main/java/com/accompany/oauth2/controller/PwdController.java @@ -42,7 +42,6 @@ public class PwdController extends BaseController { * 重置码 * @return 1:成功 2:重置码无效 3:不存在该用户 4:其它错误 */ - //@Authorization @PostMapping("/reset") @SneakyThrows public BusiResult resetPassword(HttpServletRequest request, @@ -65,6 +64,37 @@ public class PwdController extends BaseController { return new BusiResult<>(BusiStatus.SUCCESS); } + /** + * 重置密码接口,用于用户忘记密码,找回密码服务 + * + * @param newPwd + * 新密码 + * @param email + * 邮箱 + * @return 1:成功 2:重置码无效 3:不存在该用户 4:其它错误 + */ + @PostMapping("/resetByEmail") + @SneakyThrows + public BusiResult resetPasswordByEmail(HttpServletRequest request, + String email, String newPwd, String code) { + if (StringUtils.isBlank(email) || StringUtils.isBlank(newPwd) || StringUtils.isBlank(code)){ + throw new ServiceException(BusiStatus.PARAMERROR); + } + + Long uid = getUid(request); + email = decryptSensitiveInfo(request, email); + newPwd = DESUtils.DESAndBase64Decrypt(newPwd, KeyStore.DES_ENCRYPT_KEY); + + // 密码长度检查 + if(!newPwd.matches(PASSWORD_REGIX_V2)){ + return new BusiResult<>(BusiStatus.WEAK_PASSWORD); + } + + accountManageService.resetPasswordByEmailCode(uid, email, newPwd, code); + + return new BusiResult<>(BusiStatus.SUCCESS); + } + /** * 设置新密码 * @param newPwd