From 403fbe8fa8d3df96d692ad41ffa1c300b0db5493 Mon Sep 17 00:00:00 2001 From: mitao <2763622819@qq.com> Date: 星期六, 24 八月 2024 18:02:02 +0800 Subject: [PATCH] APP端登录模块接口 --- xinquan-auth/src/main/java/com/xinquan/auth/service/SysLoginService.java | 247 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 233 insertions(+), 14 deletions(-) diff --git a/xinquan-auth/src/main/java/com/xinquan/auth/service/SysLoginService.java b/xinquan-auth/src/main/java/com/xinquan/auth/service/SysLoginService.java index 144e53b..36d0fc3 100644 --- a/xinquan-auth/src/main/java/com/xinquan/auth/service/SysLoginService.java +++ b/xinquan-auth/src/main/java/com/xinquan/auth/service/SysLoginService.java @@ -2,12 +2,17 @@ import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.RandomUtil; +import com.xinquan.auth.form.AppChangePwdBody; +import com.xinquan.auth.form.AppLoginBody; import com.xinquan.auth.form.AppRegisterBody; +import com.xinquan.auth.form.VerifyResultVO; +import com.xinquan.auth.util.HuaWeiSMSUtil; import com.xinquan.common.core.constant.CacheConstants; import com.xinquan.common.core.constant.Constants; import com.xinquan.common.core.constant.SecurityConstants; import com.xinquan.common.core.constant.UserConstants; import com.xinquan.common.core.domain.R; +import com.xinquan.common.core.enums.AppUserStatusEnum; import com.xinquan.common.core.enums.UserStatus; import com.xinquan.common.core.exception.ServiceException; import com.xinquan.common.core.text.Convert; @@ -17,7 +22,13 @@ import com.xinquan.common.security.utils.SecurityUtils; import com.xinquan.system.api.RemoteUserService; import com.xinquan.system.api.domain.SysUser; +import com.xinquan.system.api.feignClient.SysUserClient; +import com.xinquan.system.api.model.AppCaptchaBody; +import com.xinquan.system.api.model.AppVerifyCellPhoneBody; +import com.xinquan.system.api.model.AppWXLoginBody; +import com.xinquan.system.api.model.AppleLoginUser; import com.xinquan.system.api.model.LoginUser; +import com.xinquan.system.api.model.WXLoginUser; import com.xinquan.user.api.domain.AppUser; import com.xinquan.user.api.domain.dto.AppUserDTO; import com.xinquan.user.api.feign.RemoteAppUserService; @@ -25,6 +36,8 @@ import java.time.LocalDateTime; import java.util.Objects; import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -53,6 +66,8 @@ @Autowired private RemoteAppUserService remoteAppUserService; + @Autowired + private SysUserClient sysUserClient; /** * 登录 */ @@ -163,7 +178,8 @@ String cellPhone = appRegisterBody.getCellPhone(); String password = appRegisterBody.getPassword(); //验证码校验 - if (!verifyCode(cellPhone, appRegisterBody.getVerifyCode())) + if (!verifyCaptcha(cellPhone, appRegisterBody.getCaptcha(), + CacheConstants.APP_REGISTER_CAPTCHA_CODE_PREFIX)) { throw new ServiceException("验证码错误"); } @@ -211,14 +227,14 @@ /** * 校验验证码 * @param cellPhone 手机号 - * @param verifyCode 验证码 + * @param captcha 验证码 * @return true/false */ - private boolean verifyCode(String cellPhone, String verifyCode) { - if (StringUtils.isNotBlank(cellPhone) && StringUtils.isNotBlank(verifyCode)) { - String key = CacheConstants.APP_CAPTCHA_CODE_PREFIX + cellPhone; + private boolean verifyCaptcha(String cellPhone, String captcha, String keyPrefix) { + if (StringUtils.isNotBlank(cellPhone) && StringUtils.isNotBlank(captcha)) { + String key = keyPrefix + cellPhone; String code = redisService.getCacheObject(key); - if (StringUtils.isNotBlank(code) && code.equals(verifyCode)) { + if (StringUtils.isNotBlank(code) && code.equals(captcha)) { redisService.deleteObject(key); return true; } @@ -227,25 +243,228 @@ } /** - * 发送验证码 - * @param cellPhone 手机号码 + * 根据类型获取对象的验证码key + * + * @param type + * @return */ - public void sendCaptchaCode(String cellPhone) { - Boolean result = redisService.hasKey( - CacheConstants.APP_CAPTCHA_CODE_PREFIX + cellPhone); + private String getCaptchaCodeByTypePrefix(Integer type) { + switch (type) { + case 1: + return CacheConstants.APP_REGISTER_CAPTCHA_CODE_PREFIX; + case 2: + return CacheConstants.APP_LOGIN_CAPTCHA_CODE_PREFIX; + case 3: + return CacheConstants.APP_PASSWORD_CAPTCHA_CODE_PREFIX; + case 4: + return CacheConstants.APP_VERIFY_CAPTCHA_CODE_PREFIX; + default: + return ""; + } + } + /** + * 发送验证码 + * + * @param cellPhone 手机号码 + * @param type + */ + public void sendCaptchaCode(String cellPhone, Integer type) { + String key = getCaptchaCodeByTypePrefix(type); + Boolean result = redisService.hasKey(key + cellPhone); if (result) { throw new ServiceException("请勿重复发送验证码"); } String code = RandomUtil.randomNumbers(6); try { - //TODO 发送短信 - log.info("发送验证码成功,手机号:{} 验证码:{}", cellPhone,code); + log.info("发送验证码成功,手机号:{} 验证码:{}", cellPhone, code); + // TODO 修改sender参数及templateId + HuaWeiSMSUtil.sendSms("[\"" + code + "\"]", cellPhone, "8823121426646", + "cf1707ec44694627b1b483b0277e12fd"); } catch (Exception e) { log.error("发送短信失败", e); throw new ServiceException("验证码发送失败"); } //将验证码放入redis - redisService.setCacheObject(CacheConstants.APP_CAPTCHA_CODE_PREFIX + cellPhone, code, 5L, + redisService.setCacheObject(key + cellPhone, code, 5L, TimeUnit.MINUTES); } + + /** + * APP账号密码登录 + * + * @param body + * @return + */ + public LoginUser appLogin(AppLoginBody body) { + + // IP黑名单校验 + String blackStr = Convert.toStr( + redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST)); + if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) { + recordLogService.recordLogininfor(body.getCellPhone(), Constants.LOGIN_FAIL, + "很遗憾,访问IP已被列入系统黑名单"); + throw new ServiceException("很遗憾,访问IP已被列入系统黑名单"); + } + // 查询用户信息 + AppUser appUser = remoteAppUserService.getUserByCondition( + AppUserDTO.builder().cellPhone(body.getCellPhone()).build(), + SecurityConstants.INNER).getData(); + if (StringUtils.isNull(appUser)) { + recordLogService.recordLogininfor(body.getCellPhone(), Constants.LOGIN_FAIL, + "登录用户不存在"); + throw new ServiceException("登录用户:" + body.getCellPhone() + " 不存在"); + } + // 1:正常 2:冻结 3:注销 + if (appUser.getUserStatus().equals(AppUserStatusEnum.FROZEN.getCode())) { + recordLogService.recordLogininfor(body.getCellPhone(), Constants.LOGIN_FAIL, + "账号已冻结"); + throw new ServiceException("账号已冻结"); + } + if (appUser.getUserStatus().equals(AppUserStatusEnum.LOGOUT.getCode())) { + recordLogService.recordLogininfor(body.getCellPhone(), Constants.LOGIN_FAIL, + "账号已注销"); + throw new ServiceException("账号已注销"); + } + // 查询系统用户信息 + SysUser sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData(); + if (StringUtils.isNull(sysUser)) { + recordLogService.recordLogininfor(body.getCellPhone(), Constants.LOGIN_FAIL, + "登录用户不存在"); + throw new ServiceException("登录用户:" + body.getCellPhone() + " 不存在"); + } + // 校验账号密码 + passwordService.validate(sysUser, body.getPassword()); + LoginUser userInfo = new LoginUser(); + userInfo.setSysUser(sysUser); + recordLogService.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_SUCCESS, + "登录成功"); + return userInfo; + } + + /** + * APP微信登录 + * + * @param body + * @return + */ + public WXLoginUser wxLogin(AppWXLoginBody body) { + // 通过wxOpenId查询APP用户信息 + R<WXLoginUser> userResult = remoteAppUserService.wxLogin(body, SecurityConstants.INNER); + if (R.FAIL == userResult.getCode()) { + throw new ServiceException(userResult.getMsg()); + } + + return userResult.getData(); + } + + /** + * 苹果登录 + * + * @param appleId 苹果id + * @return + */ + public AppleLoginUser appleLogin(String appleId) { + R<AppleLoginUser> userResult = remoteAppUserService.appleLogin(appleId, + SecurityConstants.INNER); + if (R.FAIL == userResult.getCode()) { + throw new ServiceException(userResult.getMsg()); + } + return userResult.getData(); + } + + /** + * 验证手机号 + * + * @param body + * @return + */ + public VerifyResultVO verifyPhone(AppCaptchaBody body) { + VerifyResultVO verifyResultVO = new VerifyResultVO(); + boolean b = verifyCaptcha(body.getCellPhone(), body.getCaptcha(), + CacheConstants.APP_VERIFY_CAPTCHA_CODE_PREFIX); + verifyResultVO.setSuccessFlag(b); + if (b) { + // 验证成功,删除验证码 + redisService.deleteObject( + CacheConstants.APP_VERIFY_CAPTCHA_CODE_PREFIX + body.getCellPhone()); + verifyResultVO.setSecret(IdUtil.randomUUID()); + redisService.setCacheObject( + CacheConstants.APP_PASSWORD_SECRET_PREFIX + body.getCellPhone(), + verifyResultVO.getSecret(), 10L, TimeUnit.MINUTES); + } + return verifyResultVO; + } + + public void changePassword(AppChangePwdBody body) { + Object baseSecret = redisService.getCacheObject( + CacheConstants.APP_PASSWORD_SECRET_PREFIX + body.getCellPhone()); + if (Objects.isNull(baseSecret)) { + throw new ServiceException("密码修改秘钥已失效,请重新校验手机号获取"); + } + if (!body.getSecret().equals(baseSecret.toString())) { + throw new ServiceException("密码修改秘钥不正确"); + } + // 校验密码,密码至少8个字符,不能全是字母或者数字 + String regex = "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$\n"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(body.getPassword()); + if (!matcher.matches()) { + throw new ServiceException("密码至少8个字符,不能全是字母或者数字"); + } + // 根据手机号查询用户 + AppUser appUser = remoteAppUserService.getUserByCondition( + AppUserDTO.builder().cellPhone(body.getCellPhone()).build(), + SecurityConstants.INNER).getData(); + if (Objects.isNull(appUser)) { + throw new ServiceException("用户不存在或已注销"); + } + // 查询系统用户 + SysUser sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData(); + if (Objects.isNull(sysUser)) { + throw new ServiceException("用户不存在或已注销"); + } + // 修改密码 + sysUser.setPassword(SecurityUtils.encryptPassword(body.getPassword())); + sysUserClient.updateUser(sysUser); + redisService.deleteObject(CacheConstants.APP_PASSWORD_SECRET_PREFIX + body.getCellPhone()); + } + + /** + * 验证码登录 + * + * @param body + * @return + */ + public LoginUser appCaptchaLogin(AppCaptchaBody body) { + // 校验验证码 + if (!verifyCaptcha(body.getCellPhone(), body.getCaptcha(), + CacheConstants.APP_LOGIN_CAPTCHA_CODE_PREFIX)) { + throw new ServiceException("验证码不正确"); + } + R<LoginUser> loginUserR = remoteAppUserService.appCaptchaLogin(body, + SecurityConstants.INNER); + if (R.FAIL == loginUserR.getCode()) { + throw new ServiceException(loginUserR.getMsg()); + } + return loginUserR.getData(); + } + + public WXLoginUser verifyCellPhone(AppVerifyCellPhoneBody body) { + String captcha = redisService.getCacheObject( + CacheConstants.APP_VERIFY_CAPTCHA_CODE_PREFIX + body.getCellPhone()); + if (Objects.isNull(captcha)) { + throw new ServiceException("验证码已失效,请重新获取"); + } + // 校验验证码 + if (!verifyCaptcha(body.getCellPhone(), body.getCaptcha(), + CacheConstants.APP_LOGIN_CAPTCHA_CODE_PREFIX)) { + throw new ServiceException("验证码不正确"); + } + // 更新用户系统用户信息 + R<WXLoginUser> result = remoteAppUserService.verifyCellPhone(body, SecurityConstants.INNER); + if (R.FAIL == result.getCode()) { + throw new ServiceException(result.getMsg()); + } + return result.getData(); + } } -- Gitblit v1.7.1