忘记密码相关接口:发送验证码,设置新密码等

This commit is contained in:
efren
2025-07-18 13:33:25 +08:00
parent 2e9ba48d69
commit ab5d5c888e
4 changed files with 162 additions and 0 deletions

View File

@ -1,6 +1,7 @@
package com.coscoshipping.ebtp.system.login.controller; package com.coscoshipping.ebtp.system.login.controller;
import com.chinaunicom.mall.ebtp.common.base.entity.BaseCacheUser;
import com.chinaunicom.mall.ebtp.common.base.entity.BaseResponse; import com.chinaunicom.mall.ebtp.common.base.entity.BaseResponse;
import com.chinaunicom.mall.ebtp.common.exception.common.CommonExceptionEnum; import com.chinaunicom.mall.ebtp.common.exception.common.CommonExceptionEnum;
import com.coscoshipping.ebtp.system.login.common.CaptchaGenerator; import com.coscoshipping.ebtp.system.login.common.CaptchaGenerator;
@ -104,4 +105,56 @@ public class LoginController {
public BaseResponse<Boolean> changePasswordOnFirstLogin(@RequestBody ChangePasswordVo vo) { public BaseResponse<Boolean> changePasswordOnFirstLogin(@RequestBody ChangePasswordVo vo) {
return BaseResponse.success(iBaseUserService.changeSupplierPasswordOnFirstLogin(vo.getUserId(), vo.getNewPassword())); return BaseResponse.success(iBaseUserService.changeSupplierPasswordOnFirstLogin(vo.getUserId(), vo.getNewPassword()));
} }
/**
* 忘记密码-发送验证码
* @param vo
* 传入账号(是否需要账号或手机号?如果均可,需要对应修改一下查询逻辑) 根据sysUser暂时注释查询手机号查询空继续查询sysSupplierUser获取手机号 发送验证码
* *******注意!!!!本地调试 发送验证码检查数据库中手机号字段或加断点确认手机号mobilePhone必须是自己的手机号不要随便发送给别人
* 当前接口后续看是否需要类型区分,暂时先不区分,只做供应商账号的忘记密码,集团账号可以系统管理员重置密码
* 如果需要区分类型,前端页面需要有下拉选择哪种用户
* @return 是否发送成功
*/
@ApiOperation("忘记密码-发送验证码")
@PostMapping("/forgotPassword/sendCode")
public BaseResponse<Boolean> sendForgotPasswordCode(@RequestBody LoginUserVo vo) {
BaseCacheUser baseCacheUser = iBaseUserService.getPhoneByAccount(vo.getAccount());
if (baseCacheUser == null) {
return BaseResponse.fail("账号不存在", null);
}
boolean sent = iBaseUserService.sendSmsCode(baseCacheUser);
return BaseResponse.success(sent);
}
/**
* 忘记密码-验证验证码 成功后继续设置新密码
* 如果忘记密码分开两个页面,第一个页面输入账号和验证码,校验成功第二个页面输入新密码 则调用这个接口+设置新密码接口
* 如果忘记密码仅一个页面,输入账号、验证码和新密码,则直接调用设置新密码接口
* @param vo 传递account账号 和 identifying验证码
* @return 是否验证成功
*/
@ApiOperation("忘记密码-验证验证码")
@PostMapping("/forgotPassword/verifyCode")
public BaseResponse<Boolean> verifyForgotPasswordCode(@RequestBody LoginUserVo vo) {
boolean valid = iBaseUserService.verifySmsCode(vo.getAccount(), vo.getIdentifying());
if (!valid) {
return BaseResponse.fail("验证码错误", null);
}
return BaseResponse.success(true);
}
/**
* 忘记密码-设置新密码 并删除验证码的redis
* @param vo 传递account账号 和 上一步的验证码(防止直接调用进入这里) 和 password新密码
* @return 是否设置成功
*/
@ApiOperation("忘记密码-设置新密码")
@PostMapping("/forgotPassword/reset")
public BaseResponse<Boolean> resetForgotPassword(@RequestBody LoginUserVo vo) {
boolean valid = iBaseUserService.verifySmsCode(vo.getAccount(), vo.getIdentifying());
if (!valid) {
return BaseResponse.fail("验证码错误", null);
}
return BaseResponse.success(iBaseUserService.resetPasswordWithCode(vo.getAccount(), vo.getPassword()));
}
} }

View File

@ -1,6 +1,7 @@
package com.coscoshipping.ebtp.system.login.service; package com.coscoshipping.ebtp.system.login.service;
import com.chinaunicom.mall.ebtp.cloud.security.starter.entity.SecurityEntity; import com.chinaunicom.mall.ebtp.cloud.security.starter.entity.SecurityEntity;
import com.chinaunicom.mall.ebtp.common.base.entity.BaseCacheUser;
import com.chinaunicom.mall.ebtp.common.base.service.IBaseService; import com.chinaunicom.mall.ebtp.common.base.service.IBaseService;
import com.coscoshipping.ebtp.system.login.entity.BaseSelf; import com.coscoshipping.ebtp.system.login.entity.BaseSelf;
import com.coscoshipping.ebtp.system.user.entity.SysUser; import com.coscoshipping.ebtp.system.user.entity.SysUser;
@ -43,4 +44,24 @@ public interface BaseUserService extends IBaseService<SysUser> {
* @return 是否修改成功 * @return 是否修改成功
*/ */
boolean changeSupplierPasswordOnFirstLogin(Long userId, String newPassword); boolean changeSupplierPasswordOnFirstLogin(Long userId, String newPassword);
/**
* 根据账号获取手机号
*/
BaseCacheUser getPhoneByAccount(String account);
/**
* 发送短信验证码到指定手机号并存入Redis
*/
boolean sendSmsCode(BaseCacheUser baseCacheUser);
/**
* 校验账号和验证码
*/
boolean verifySmsCode(String account, String code);
/**
* 校验通过后重置密码
*/
boolean resetPasswordWithCode(String account, String newPassword);
} }

View File

@ -16,6 +16,11 @@ import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import cn.hutool.core.util.IdUtil;
import com.chinaunicom.mall.ebtp.common.base.entity.BaseResponse;
import com.chinaunicom.mall.ebtp.common.sms.client.SmsFeignClient;
import com.chinaunicom.mall.ebtp.common.sms.entity.SmsSendResponse;
import com.chinaunicom.mall.ebtp.common.util.PropertyUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
@ -102,6 +107,9 @@ public class BaseUserServiceImpl extends BaseServiceImpl<BaseUserMapper, SysUser
@Qualifier("userinfoRedisTemplate") @Qualifier("userinfoRedisTemplate")
private RedisTemplate<String, Object> userinfoRedisTemplate; private RedisTemplate<String, Object> userinfoRedisTemplate;
@Autowired
private SmsFeignClient smsFeignClient;
@Override @Override
public BaseSelf idcardLogin(String account, String password) { public BaseSelf idcardLogin(String account, String password) {
try { try {
@ -120,6 +128,7 @@ public class BaseUserServiceImpl extends BaseServiceImpl<BaseUserMapper, SysUser
byte[] decode = RSA.decryptByPrivateKey(RSA.decryptBASE64(password), privateKey); byte[] decode = RSA.decryptByPrivateKey(RSA.decryptBASE64(password), privateKey);
String pw = new String(decode); String pw = new String(decode);
// String pw = password;
if (!Md5Util.encode(pw).equals(user.getPassword())) { if (!Md5Util.encode(pw).equals(user.getPassword())) {
throw new RuntimeException("用户名或密码错误!"); throw new RuntimeException("用户名或密码错误!");
@ -617,6 +626,84 @@ public class BaseUserServiceImpl extends BaseServiceImpl<BaseUserMapper, SysUser
return this.updateById(updateUser); return this.updateById(updateUser);
} }
@Override
public BaseCacheUser getPhoneByAccount(String account) {
BaseCacheUser cacheUser = new BaseCacheUser();
// 先查集团用户SysUser
// List<SysUser> userList = this.list(new LambdaQueryWrapper<SysUser>().eq(SysUser::getEmployeeNumber, account));
// if (userList != null && !userList.isEmpty()) {
// SysUser user = userList.get(0);
// cacheUser.setMobilePhone(user.getMobile());
// cacheUser.setUserType("0"); // 集团用户
// cacheUser.setUserId(user.getUserId());
// cacheUser.setLoginName(user.getEmployeeNumber());
// redisTemplate.opsForValue().set("FORGOT_PWD_USER:" + account, cacheUser, 10, TimeUnit.MINUTES);
// return cacheUser;
// }
// 再查供应商用户SysSupplierUser
List<SysSupplierUser> supplierUserList = sysSupplierUserMapper.selectList(
new LambdaQueryWrapper<SysSupplierUser>().eq(SysSupplierUser::getUsername, account)
);
if (supplierUserList != null && !supplierUserList.isEmpty()) {
SysSupplierUser user = supplierUserList.get(0);
cacheUser.setMobilePhone(user.getMobile());
cacheUser.setUserType("2"); // 供应商
cacheUser.setUserId(user.getUserId().toString());
cacheUser.setLoginName(user.getUsername());
redisTemplate.opsForValue().set("FORGOT_PWD_USER:" + account, cacheUser, 10, TimeUnit.MINUTES);
return cacheUser;
}
return null;
}
@Override
public boolean sendSmsCode(BaseCacheUser baseCacheUser) {
// 生成验证码
String code = String.valueOf((int)((Math.random() * 9 + 1) * 100000));
// 发送短信
log.info("发送短信验证码到:{},验证码:{}", baseCacheUser.getMobilePhone(), code);
String message = "您的验证码是:" + code + "请在5分钟内输入。";
BaseResponse<SmsSendResponse.TemplateSMS> templateSMSBaseResponse = smsFeignClient.sendSms(new String[]{baseCacheUser.getMobilePhone()}, "1180212", new String[]{message}, PropertyUtils.getSnowflakeId(), null);
redisTemplate.opsForValue().set("FORGOT_PWD_CODE:" + baseCacheUser.getLoginName(), code, 5, TimeUnit.MINUTES);
return templateSMSBaseResponse.isSuccess();
}
@Override
public boolean verifySmsCode(String account, String code) {
Object redisCode = redisTemplate.opsForValue().get("FORGOT_PWD_CODE:" + account);
return code != null && code.equals(redisCode);
}
@Override
public boolean resetPasswordWithCode(String account, String newPassword) {
Object redisCode = redisTemplate.opsForValue().get("FORGOT_PWD_CODE:" + account);
if (redisCode == null) return false;
// 获取用户信息
BaseCacheUser cacheUser = (BaseCacheUser) redisTemplate.opsForValue().get("FORGOT_PWD_USER:" + account);
if (cacheUser == null || cacheUser.getUserType() == null) return false;
boolean result = false;
if ("0".equals(cacheUser.getUserType())) {
// 集团用户
SysUser user = this.getById(cacheUser.getUserId());
if (user == null) return false;
user.setPassword(Md5Util.encode(newPassword));
result = this.updateById(user);
} else if ("2".equals(cacheUser.getUserType())) {
// 供应商
SysSupplierUser supplierUser = sysSupplierUserMapper.selectById(cacheUser.getUserId());
if (supplierUser == null) return false;
String mm2 = RSA.encrypt(newPassword, publickey);
supplierUser.setPassword(Md5Util.encode(newPassword));
result = sysSupplierUserMapper.updateById(supplierUser) > 0;
} else {
return false;
}
// 删除验证码
redisTemplate.delete("FORGOT_PWD_CODE:" + account);
redisTemplate.delete("FORGOT_PWD_USER:" + account);
return result;
}
public static void main(String args[]) throws Exception { public static void main(String args[]) throws Exception {
// String rsa = // String rsa =
// "ObMojRm4G31O91lJDyV7rT7fmkJ0x/tMz+t2gZa1M5RtZm6cTiaAT6eblAQzjuMbNNU6DoD/YloITzn2jnQH4g2nMj1Y8TXdSEK/q8QSoLb8QVb26SuMt1xuv1hklU0yzkqCtGW7GnRArMMlgQjh04GwAcj6TikEFjKvEGGETm4="; // "ObMojRm4G31O91lJDyV7rT7fmkJ0x/tMz+t2gZa1M5RtZm6cTiaAT6eblAQzjuMbNNU6DoD/YloITzn2jnQH4g2nMj1Y8TXdSEK/q8QSoLb8QVb26SuMt1xuv1hklU0yzkqCtGW7GnRArMMlgQjh04GwAcj6TikEFjKvEGGETm4=";

View File

@ -227,6 +227,7 @@ allow:
- ^GET\./?v1/userinfo/oauth/check_token$ - ^GET\./?v1/userinfo/oauth/check_token$
- ^GET\./?outer/v1.0/auth/.*$ - ^GET\./?outer/v1.0/auth/.*$
- ^GET\./?v1/login/getCaptcha$ - ^GET\./?v1/login/getCaptcha$
- ^POST\./?v1/login/forgotPassword/.*$
#feign调用 #feign调用
mall: mall: