提交 6e1f6e82 编写于 作者: rushui.chen's avatar rushui.chen

20190917 控制验证码的发送逻辑和检验测试

上级 3e62a3e1
流水线 #14592 已失败 于阶段
in 0 second
...@@ -78,8 +78,7 @@ public class LoginController extends AccountBaseController { ...@@ -78,8 +78,7 @@ public class LoginController extends AccountBaseController {
@PostMapping(value = "/login-register") @PostMapping(value = "/login-register")
public PicaResponse loginAndRegister(@RequestBody EncryptEntity entity) throws Exception { public PicaResponse loginAndRegister(@RequestBody EncryptEntity entity) throws Exception {
BaseRequest request = CryptoUtil.decrypt(entity, BaseRequest.class); BaseRequest request = CryptoUtil.decrypt(entity, BaseRequest.class);
accountUtils.checkMobilePhone(request.getMobile()); accountUtils.checkMobilePhoneAndAuthCode(request.getMobile(), AccountTypeEnum.SYSCODE_TYPE_LOGIN.getCode() + "",request.getSysCode());
accountUtils.getAuthCodeKey(request.getMobile(), AccountTypeEnum.SYSCODE_TYPE_LOGIN.getCode() + "");
request.setProductType(super.getProductType()); request.setProductType(super.getProductType());
request.setSourceType(super.getSourceType()); request.setSourceType(super.getSourceType());
request.setLoginIp(super.getIpAddr()); request.setLoginIp(super.getIpAddr());
...@@ -102,8 +101,7 @@ public class LoginController extends AccountBaseController { ...@@ -102,8 +101,7 @@ public class LoginController extends AccountBaseController {
@PostMapping(value = "/login/wechat/step2") @PostMapping(value = "/login/wechat/step2")
public PicaResponse loginByWeChatStep(@RequestBody EncryptEntity entity) throws Exception { public PicaResponse loginByWeChatStep(@RequestBody EncryptEntity entity) throws Exception {
BaseRequest request = CryptoUtil.decrypt(entity, BaseRequest.class); BaseRequest request = CryptoUtil.decrypt(entity, BaseRequest.class);
accountUtils.checkMobilePhone(request.getMobile()); accountUtils.checkMobilePhoneAndAuthCode(request.getMobile(), AccountTypeEnum.SYSCODE_TYPE_WE_CHAT.getCode() + "", request.getSysCode());
accountUtils.checkAuthCode(request.getMobile(), AccountTypeEnum.SYSCODE_TYPE_WE_CHAT.getCode() + "", request.getSysCode());
request.setProductType(super.getProductType()); request.setProductType(super.getProductType());
request.setSourceType(super.getSourceType()); request.setSourceType(super.getSourceType());
request.setLoginIp(super.getIpAddr()); request.setLoginIp(super.getIpAddr());
......
...@@ -30,8 +30,7 @@ public class ModifyMobileController extends AccountBaseController { ...@@ -30,8 +30,7 @@ public class ModifyMobileController extends AccountBaseController {
Integer acctId = super.getAcctId(); Integer acctId = super.getAcctId();
BaseRequest request = CryptoUtil.decrypt(entity, BaseRequest.class); BaseRequest request = CryptoUtil.decrypt(entity, BaseRequest.class);
String mobile = request.getMobile(); String mobile = request.getMobile();
accountUtils.checkMobilePhone(mobile); accountUtils.checkMobilePhoneAndAuthCode(mobile, AccountTypeEnum.SYSCODE_TYPE_MODIFY_MOBILE.getCode() + "", request.getSysCode());
accountUtils.checkAuthCode(mobile, AccountTypeEnum.SYSCODE_TYPE_MODIFY_MOBILE.getCode() + "", request.getSysCode());
modifyMobileService.modify(acctId, mobile); modifyMobileService.modify(acctId, mobile);
return PicaResponse.toResponse(); return PicaResponse.toResponse();
} }
......
...@@ -62,8 +62,7 @@ public class PasswordController extends AccountBaseController { ...@@ -62,8 +62,7 @@ public class PasswordController extends AccountBaseController {
@PostMapping(value = "/reset") @PostMapping(value = "/reset")
public PicaResponse forgetPassword(@RequestBody EncryptEntity entity) throws Exception { public PicaResponse forgetPassword(@RequestBody EncryptEntity entity) throws Exception {
BaseRequest request = CryptoUtil.decrypt(entity, BaseRequest.class); BaseRequest request = CryptoUtil.decrypt(entity, BaseRequest.class);
accountUtils.checkMobilePhone(request.getMobile()); accountUtils.checkMobilePhoneAndAuthCode(request.getMobile(), AccountTypeEnum.SYSCODE_TYPE_RESET_PASSWORD.getCode() + "", request.getSysCode());
accountUtils.checkAuthCode(request.getMobile(), AccountTypeEnum.SYSCODE_TYPE_RESET_PASSWORD.getCode() + "", request.getSysCode());
if (StringUtils.isEmpty(request.getPassword())) { if (StringUtils.isEmpty(request.getPassword())) {
throw new AccountException(AccountExceptionEnum.PICA_PASSWORD_ERROR); throw new AccountException(AccountExceptionEnum.PICA_PASSWORD_ERROR);
} }
......
...@@ -23,13 +23,15 @@ public class RegisterController extends AccountBaseController { ...@@ -23,13 +23,15 @@ public class RegisterController extends AccountBaseController {
@Autowired @Autowired
private RegisterService registerService; private RegisterService registerService;
@Autowired
private AccountUtils accountUtils;
@ApiOperation("注册接口") @ApiOperation("注册接口")
@PostMapping(value = "") @PostMapping(value = "")
public PicaResponse<String> register(@RequestBody EncryptEntity entity) throws Exception { public PicaResponse<String> register(@RequestBody EncryptEntity entity) throws Exception {
BaseRequest request = CryptoUtil.decrypt(entity, BaseRequest.class); BaseRequest request = CryptoUtil.decrypt(entity, BaseRequest.class);
AccountUtils.checkMobilePhone(request.getMobile()); accountUtils.checkMobilePhoneAndAuthCode(request.getMobile(),AccountTypeEnum.SYSCODE_TYPE_REGISTER.getCode()+"", request.getSysCode());
AccountUtils.getAuthCodeKey(request.getSysCode(), AccountTypeEnum.SYSCODE_TYPE_REGISTER.getCode() + ""); accountUtils.checkPassword(request.getPassword());
AccountUtils.checkPassword(request.getPassword());
request.setFlag(AccountTypeEnum.SYSCODE_TYPE_REGISTER.getCode()); request.setFlag(AccountTypeEnum.SYSCODE_TYPE_REGISTER.getCode());
request.setProductType(super.getProductType()); request.setProductType(super.getProductType());
request.setSourceType(super.getSourceType()); request.setSourceType(super.getSourceType());
......
package com.pica.cloud.account.account.server.controller; package com.pica.cloud.account.account.server.controller;
import com.pica.cloud.account.account.server.entity.Account;
import com.pica.cloud.account.account.server.entity.AccountInfoEntity; import com.pica.cloud.account.account.server.entity.AccountInfoEntity;
import com.pica.cloud.account.account.server.entity.AccountUnionEntity; import com.pica.cloud.account.account.server.entity.AccountUnionEntity;
import com.pica.cloud.account.account.server.entity.EncryptEntity; import com.pica.cloud.account.account.server.entity.EncryptEntity;
...@@ -15,8 +16,10 @@ import com.pica.cloud.foundation.entity.PicaResponse; ...@@ -15,8 +16,10 @@ import com.pica.cloud.foundation.entity.PicaResponse;
import com.pica.cloud.foundation.redis.ICacheClient; import com.pica.cloud.foundation.redis.ICacheClient;
import com.pica.cloud.foundation.utils.utils.CommonUtil; import com.pica.cloud.foundation.utils.utils.CommonUtil;
import com.pica.cloud.foundation.utils.utils.EncryptCreateUtil; import com.pica.cloud.foundation.utils.utils.EncryptCreateUtil;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.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;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
...@@ -41,7 +44,6 @@ public class SysCodeController extends AccountBaseController { ...@@ -41,7 +44,6 @@ public class SysCodeController extends AccountBaseController {
@Qualifier("cacheMigrateClient") @Qualifier("cacheMigrateClient")
private ICacheClient cacheClient; private ICacheClient cacheClient;
/** /**
* 必须要传递flag类型 * 必须要传递flag类型
* *
...@@ -75,27 +77,40 @@ public class SysCodeController extends AccountBaseController { ...@@ -75,27 +77,40 @@ public class SysCodeController extends AccountBaseController {
/** /**
* 验证码发送逻辑 * 验证码发送逻辑
* 1)随机数生成验证码;
* 2)验证码失效时间十分钟;
* 3)同一个业务一个手机号一分钟只能发送一次:提示:请X秒后重试.(用手机号区别用户,用flag区别业务类型)
* *
* @param mobilePhone * @param mobilePhone
* @param flag * @param flag
*/ */
private void processSysCode(String mobilePhone, Integer flag) { private void processSysCode(String mobilePhone, Integer flag) {
//随机生成验证码 String authCodeKey = this.getAuthCodeKey(mobilePhone, flag.toString());
String authCode = CommonUtil.createValidateCode(); String authCodeKeySecure = authCodeKey + "-secure";
String message = "您的验证码是" + authCode + ",在10分钟内有效。如非本人操作,请忽略本短信!"; //如果存在,说明刚刚发送过验证码
//判断账号是否已经存在 if (cacheClient.exists(authCodeKey)) {
AccountInfoEntity accountInfoEntity = accountInfoDetailMapper.selectByMobile(mobilePhone); Long time = cacheClient.get(this.getAuthCodeKey(mobilePhone, flag.toString()) + "-secure", Long.class);
long senderId = accountInfoEntity == null ? 0L : accountInfoEntity.getId(); if (time == null) {
//验证码保存到redis,失效时间10分钟 time = 0L;
cacheClient.set(this.getAuthCodeKey(mobilePhone, flag + ""), authCode, 600); }
//发送短信 int remainTime = 59 - (int) (System.currentTimeMillis() - time) / 1000;
super.sendMobileMessage(mobilePhone, message, senderId); if (remainTime > 0) {
throw new AccountException(AccountExceptionEnum.PICA_SYSCODE_RETRY.getCode(),
AccountExceptionEnum.PICA_SYSCODE_RETRY.getMessage().replace("X", String.valueOf(remainTime)));
}
} else {
String authCode = CommonUtil.createValidateCode();
String message = "您的验证码是" + authCode + ",在10分钟内有效。如非本人操作,请忽略本短信!";
AccountInfoEntity accountInfoEntity = accountInfoDetailMapper.selectByMobile(mobilePhone);
long senderId = accountInfoEntity == null ? 0L : accountInfoEntity.getId();
cacheClient.set(this.getAuthCodeKey(mobilePhone, flag.toString()), authCode, 600);
cacheClient.set(authCodeKeySecure, System.currentTimeMillis(), 60);
super.sendMobileMessage(mobilePhone, message, senderId);
}
} }
//获取验证码redis key //获取验证码redis key
private String getAuthCodeKey(String mobilePhone, String flag) { private String getAuthCodeKey(String mobilePhone, String flag) {
return AUTH_CODE_PREFIX + flag + "-" + EncryptCreateUtil.encrypt(mobilePhone); return AUTH_CODE_PREFIX + flag + "-" + EncryptCreateUtil.encrypt(mobilePhone);
} }
} }
...@@ -22,7 +22,8 @@ public enum AccountExceptionEnum { ...@@ -22,7 +22,8 @@ public enum AccountExceptionEnum {
PICA_PASSWORD_EQUAL("216514", "旧密码与新密码不能相同"), PICA_PASSWORD_EQUAL("216514", "旧密码与新密码不能相同"),
PICA_UNBIND_MOBILE("216515", "该手机号未绑定微信"), PICA_UNBIND_MOBILE("216515", "该手机号未绑定微信"),
PICA_MOBILE_SAME("216516", "新手机号与旧手机号不能相同"), PICA_MOBILE_SAME("216516", "新手机号与旧手机号不能相同"),
PICA_PARAMS_ERROR("216517", "传递参数有误"); PICA_PARAMS_ERROR("216517", "传递参数有误"),
PICA_SYSCODE_RETRY("216518", "请X秒后重试");
private String code; private String code;
......
...@@ -4,11 +4,14 @@ package com.pica.cloud.account.account.server.service.impl; ...@@ -4,11 +4,14 @@ package com.pica.cloud.account.account.server.service.impl;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.pica.cloud.account.account.server.constants.Constants; import com.pica.cloud.account.account.server.constants.Constants;
import com.pica.cloud.account.account.server.entity.*; import com.pica.cloud.account.account.server.entity.*;
import com.pica.cloud.account.account.server.enums.AccountTypeEnum;
import com.pica.cloud.account.account.server.enums.AccountExceptionEnum; import com.pica.cloud.account.account.server.enums.AccountExceptionEnum;
import com.pica.cloud.account.account.server.enums.AccountTypeEnum;
import com.pica.cloud.account.account.server.log.AccountLogEntityUtils; import com.pica.cloud.account.account.server.log.AccountLogEntityUtils;
import com.pica.cloud.account.account.server.log.AccountLogUtils; import com.pica.cloud.account.account.server.log.AccountLogUtils;
import com.pica.cloud.account.account.server.mapper.*; import com.pica.cloud.account.account.server.mapper.AccountInfoDetailMapper;
import com.pica.cloud.account.account.server.mapper.AccountUnionMapper;
import com.pica.cloud.account.account.server.mapper.AccountWeChatInfoMapper;
import com.pica.cloud.account.account.server.mapper.DoctorMapper;
import com.pica.cloud.account.account.server.req.AccountReq; import com.pica.cloud.account.account.server.req.AccountReq;
import com.pica.cloud.account.account.server.req.BaseRequest; import com.pica.cloud.account.account.server.req.BaseRequest;
import com.pica.cloud.account.account.server.service.LoginService; import com.pica.cloud.account.account.server.service.LoginService;
...@@ -17,10 +20,8 @@ import com.pica.cloud.account.account.server.util.AccountUtils; ...@@ -17,10 +20,8 @@ import com.pica.cloud.account.account.server.util.AccountUtils;
import com.pica.cloud.account.account.server.util.TokenUtils; import com.pica.cloud.account.account.server.util.TokenUtils;
import com.pica.cloud.account.account.server.util.WeChatUtils; import com.pica.cloud.account.account.server.util.WeChatUtils;
import com.pica.cloud.foundation.entity.PicaException; import com.pica.cloud.foundation.entity.PicaException;
import com.pica.cloud.foundation.entity.PicaResultCode;
import com.pica.cloud.foundation.redis.ICacheClient; import com.pica.cloud.foundation.redis.ICacheClient;
import com.pica.cloud.foundation.utils.utils.EncryptCreateUtil; import com.pica.cloud.foundation.utils.utils.EncryptCreateUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -136,12 +137,6 @@ public class LoginServiceImpl implements LoginService { ...@@ -136,12 +137,6 @@ public class LoginServiceImpl implements LoginService {
private String processLogin(BaseRequest baseRequest, Integer acctId, Integer loginType) { private String processLogin(BaseRequest baseRequest, Integer acctId, Integer loginType) {
Date currentTime = new Date(); Date currentTime = new Date();
Long userId = accountUtils.getUserIdByAcctId(baseRequest.getProductType(), acctId); Long userId = accountUtils.getUserIdByAcctId(baseRequest.getProductType(), acctId);
//验证码登陆:只要相同即可成功
AccountReq accountReq = new AccountReq();
accountReq.setAuthCode(baseRequest.getSysCode());
accountReq.setMobilePhone(baseRequest.getMobile());
accountReq.setFlag("0");
checkAuthCode(accountReq);
Account account = new Account(); Account account = new Account();
account.setId(userId); account.setId(userId);
account.setAcctId(acctId); account.setAcctId(acctId);
...@@ -297,22 +292,4 @@ public class LoginServiceImpl implements LoginService { ...@@ -297,22 +292,4 @@ public class LoginServiceImpl implements LoginService {
accountWeChatInfoEntity.setLanguage(weChatUserInfoEntity.getLanguage()); accountWeChatInfoEntity.setLanguage(weChatUserInfoEntity.getLanguage());
accountWeChatInfoMapper.insertSelective(accountWeChatInfoEntity); accountWeChatInfoMapper.insertSelective(accountWeChatInfoEntity);
} }
//校验验证码
private void checkAuthCode(AccountReq req) {
String flag = StringUtils.isBlank(req.getFlag()) ? "0" : req.getFlag();
if (StringUtils.isBlank(req.getAuthCode())) {
throw new PicaException(PicaResultCode.PARAM_IS_INVALID.code(), "短信验证码错误");
}
String authCodeKey = AccountUtils.getAuthCodeKey(req.getMobilePhone(), flag);
String cacheCode = redisClient.get(authCodeKey); //从redis获取验证码
if (StringUtils.isBlank(cacheCode)) {
throw new PicaException(PicaResultCode.RESULE_DATA_NONE.code(), "短信验证码已过期,请重新获取");
}
if (!StringUtils.equals(req.getAuthCode(), cacheCode)) {
throw new PicaException(PicaResultCode.PARAM_IS_INVALID.code(), "短信验证码错误");
}
//清除验证码
redisClient.del(authCodeKey);
}
} }
...@@ -33,6 +33,7 @@ public class AccountUtils { ...@@ -33,6 +33,7 @@ public class AccountUtils {
private DoctorMapper doctorInfoMapper; private DoctorMapper doctorInfoMapper;
private static final String AUTH_CODE_PREFIX = "authCode-"; private static final String AUTH_CODE_PREFIX = "authCode-";
private static final String AUTH_CODE_COUNT_PREFIX = "authCode-count-";
//手机格式校验 //手机格式校验
public static void checkMobilePhone(String mobilePhone) { public static void checkMobilePhone(String mobilePhone) {
...@@ -81,11 +82,19 @@ public class AccountUtils { ...@@ -81,11 +82,19 @@ public class AccountUtils {
throw new PicaException(PicaResultCode.PARAM_IS_INVALID.code(), "短信验证码错误"); throw new PicaException(PicaResultCode.PARAM_IS_INVALID.code(), "短信验证码错误");
} }
String authCodeKey = AccountUtils.getAuthCodeKey(mobile, flag); String authCodeKey = AccountUtils.getAuthCodeKey(mobile, flag);
//验证码3次校验测试不通过,直接删除
String authCodeCount = AUTH_CODE_COUNT_PREFIX + flag + "-" + EncryptCreateUtil.encrypt(mobile);
if (cacheClient.exists(authCodeCount) && Integer.parseInt(cacheClient.get(authCodeCount)) > 2) {
cacheClient.del(authCodeKey);
}
String cacheCode = cacheClient.get(authCodeKey); //从redis获取验证码 String cacheCode = cacheClient.get(authCodeKey); //从redis获取验证码
if (org.apache.commons.lang.StringUtils.isBlank(cacheCode)) { if (org.apache.commons.lang.StringUtils.isBlank(cacheCode)) {
throw new PicaException(PicaResultCode.RESULE_DATA_NONE.code(), "短信验证码已过期,请重新获取"); //第四次删除计数器
cacheClient.del(authCodeCount);
throw new PicaException(PicaResultCode.RESULE_DATA_NONE.code(), "短信验证码已失效,请重新获取");
} }
if (!org.apache.commons.lang.StringUtils.equals(sysCode, cacheCode)) { if (!org.apache.commons.lang.StringUtils.equals(sysCode, cacheCode)) {
cacheClient.incr(authCodeCount);
throw new PicaException(PicaResultCode.PARAM_IS_INVALID.code(), "短信验证码错误"); throw new PicaException(PicaResultCode.PARAM_IS_INVALID.code(), "短信验证码错误");
} }
cacheClient.del(authCodeKey); cacheClient.del(authCodeKey);
...@@ -111,7 +120,7 @@ public class AccountUtils { ...@@ -111,7 +120,7 @@ public class AccountUtils {
* @return * @return
*/ */
public static String getSourceType(Integer registerSource) { public static String getSourceType(Integer registerSource) {
String sourceType = null; String sourceType = StringUtils.EMPTY;
switch (registerSource) { switch (registerSource) {
case 3: case 3:
sourceType = "web"; sourceType = "web";
......
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册