这里仅给出关键代码
/**
* 发送验证码
* 1、匹配图形验证码是否正常
* 2、发送验证码
*
* @param to
* @param captcha
* @return
*/
@ApiOperation("发送邮箱注册验证码")
@GetMapping("send_code")
public JsonData sendRegisterCode(@RequestParam(value = "to",required = true) String to,
@RequestParam(value = "captcha",required = true) String captcha,
HttpServletRequest request){
String key = getCaptchaKey(request);
//获取缓存key
String cacheCaptcha = redisTemplate.opsForValue().get(key);
//匹配图形验证码是否一样
if(captcha !=null && cacheCaptcha !=null && captcha.equalsIgnoreCase(cacheCaptcha)){
//成功
redisTemplate.delete(key);
JsonData jsonData = notifyService.sendCode(SendCodeEnum.USER_REGISTER,to);
return jsonData;
}else{
return JsonData.buildResult(BizCodeEnum.CODE_CAPTCHA_ERROR);
}
} import lombok.extern.slf4j.Slf4j;
import net.xdclass.enums.BizCodeEnum;
import net.xdclass.enums.SendCodeEnum;
import net.xdclass.component.MailService;
import net.xdclass.service.NotifyService;
import net.xdclass.utils.CheckUtil;
import net.xdclass.utils.CommonUtil;
import net.xdclass.utils.JsonData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class NotifyServiceImpl implements NotifyService {
@Autowired
private MailService mailService;
/**
* 验证码的标题
*/
private static final String SUBJECT= "验证码";
/**
* 验证码的内容
*/
private static final String CONTENT= "您的验证码是%s,有效时间是60秒,打死也不要告诉任何人";
@Override
public JsonData sendCode(SendCodeEnum sendCodeEnum, String to) {
if(CheckUtil.isEmail(to)){
//邮箱验证码
String code = CommonUtil.getRandomCode(6);
mailService.sendMail(to,SUBJECT,String.format(CONTENT,code));
return JsonData.buildSuccess();
} else if(CheckUtil.isPhone(to)){
//短信验证码
}
return JsonData.buildResult(BizCodeEnum.CODE_TO_ERROR);
}
} public interface NotifyService {
JsonData sendCode(SendCodeEnum sendCodeEnum, String to );
}
为了避免如果用户疯狂搞你,一直重复请求验证码,所以这里家人防止对面的操作,原理就是,在key的拼接,也就是微服务上说的第三种解决方案,在key生成的时候拼接上时间戳,然后存储到Redis,随后用户请求的时候进行查询,如果时间戳不符合,那么将拒绝发送,这里给出具体代码
/**
* 验证码的内容
*/
private static final String CONTENT= "您的验证码是%s,有效时间是60秒,打死也不要告诉任何人";
/**
* 前置:判断是否重复发送
*
* 1、存储验证码到缓存
*
* 2、发送邮箱验证码
*
* 后置:存储发送记录
*
* @param sendCodeEnum
* @param to
* @return
*/
@Override
public JsonData sendCode(SendCodeEnum sendCodeEnum, String to) {
String cacheKey = String.format(CacheKey.CHECK_CODE_KEY,sendCodeEnum.name(),to);
String cacheValue = redisTemplate.opsForValue().get(cacheKey);
//如果不为空,则判断是否60秒内重复发送
if(StringUtils.isNotBlank(cacheValue)){
long ttl = Long.parseLong(cacheValue.split("_")[1]);
//当前时间戳-验证码发送时间戳,如果小于60秒,则不给重复发送
if(CommonUtil.getCurrentTimestamp() - ttl < 1000*60){
log.info("重复发送验证码,时间间隔:{} 秒",(CommonUtil.getCurrentTimestamp()-ttl)/1000);
return JsonData.buildResult(BizCodeEnum.CODE_LIMITED);
}
}
//拼接验证码 2322_324243232424324
String code = CommonUtil.getRandomCode(6);
String value = code+"_"+CommonUtil.getCurrentTimestamp();
redisTemplate.opsForValue().set(cacheKey,value,CODE_EXPIRED, TimeUnit.MILLISECONDS);
if(CheckUtil.isEmail(to)){
//邮箱验证码
mailService.sendMail(to,SUBJECT,String.format(CONTENT,code));
return JsonData.buildSuccess();
} else if(CheckUtil.isPhone(to)){
//短信验证码
}
return JsonData.buildResult(BizCodeEnum.CODE_TO_ERROR);
} 接下来三步走,第一步获取验证码,第二步根据验证码请求发送邮箱验证码,第三步收获成功[aru_17]









本文作者为DBC,转载请注明。