做一个短信验证码发送与校验的demo,就是我们常见的那种:输入手机号码,发送手机验证码,登录,只列了流程和代码,验证过了可以用。
有改进建议的朋友欢迎沟通。
短验发送流程
代码
/**
* 发送短信验证码
*/
@PostMapping("/sendTextCode")
public AjaxResult sendTextCode(@RequestBody LoginBody loginBody) {
log.info("发送验证码 开始");
AjaxResult ajaxResult = authorizeService.sendTextCode(loginBody);
log.info("发送验证码 结束");
return ajaxResult;
}
/**
* 发送短信验证码
*/
@Override
public AjaxResult sendTextCode(LoginBody loginBody) {
String phoneNumber = loginBody.getPhoneNumber();
String verifyKey = CacheConstants.TEXT_CODE_KEY + phoneNumber;
log.info("短信验证码-verifyKey:{}", verifyKey);
Long expire = redisCache.getExpire(verifyKey);
log.info("短信验证码-verifyKey-{} 的剩余有效时长为:{}", verifyKey, expire);
//未过期,不发送短信
if (0 < expire) {
log.info("短信验证码-verifyKey-{} 仍在有效期内", verifyKey);
return AjaxResult.success("验证码仍在有效期内", phoneNumber);
}
//手机号码
if (StringUtils.isEmpty(phoneNumber)) {
log.error("手机号码不能为空");
return AjaxResult.success("手机号码不能为空");
}
//accessKeyId
String accessKeyId = sysConfigService.selectConfigByKey("sys.login.text.accessKeyId");
log.info("短信服务-accessKeyId:{}", accessKeyId);
if (StringUtils.isEmpty(accessKeyId)) {
log.error("未配置'短信服务-accessKeyId',请联系管理员进行配置");
return AjaxResult.success("验证码发送失败");
}
//accessKeySecret
String accessKeySecret = sysConfigService.selectConfigByKey("sys.login.text.accessKeySecret");
log.info("短信服务-accessKeySecret:{}", accessKeySecret);
if (StringUtils.isEmpty(accessKeySecret)) {
log.error("未配置'短信服务-accessKeySecret',请联系管理员进行配置");
return AjaxResult.error("验证码发送失败");
}
//短信签名名称
String signName = sysConfigService.selectConfigByKey("sys.login.text.signName");
log.info("短信服务-signName:{}", signName);
if (StringUtils.isEmpty(signName)) {
log.error("未配置'短信服务-signName',请联系管理员进行配置");
return AjaxResult.error("验证码发送失败");
}
//短信模板Code
String templateCode = sysConfigService.selectConfigByKey("sys.login.text.templateCode");
log.info("短信服务-templateCode:{}", templateCode);
if (StringUtils.isEmpty(templateCode)) {
log.error("未配置'短信服务-templateCode',请联系管理员进行配置");
return AjaxResult.error("验证码发送失败");
}
//短信模板变量
String templateParam = sysConfigService.selectConfigByKey("sys.login.text.templateParam");
log.info("短信服务-templateParam:{}", templateParam);
if (StringUtils.isEmpty(templateParam)) {
log.error("未配置'短信服务-templateParam',请联系管理员进行配置");
return AjaxResult.error("验证码发送失败");
}
String code = String.valueOf(1000 + new Random().nextInt(8999));
log.info("生成4位随机验证码:{}", code);
Map<String, String> templateParamMap = new HashMap<>();
templateParamMap.put(templateParam, code);
try {
Client client = TextMsgUtil.createClient(accessKeyId, accessKeySecret);
log.info("调用短信服务发送短信 开始");
SendSmsRequest sendSmsRequest = new SendSmsRequest().setSignName(signName).setTemplateCode(templateCode).setPhoneNumbers(phoneNumber).setTemplateParam(JSON.toJSONString(templateParamMap));
SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, new RuntimeOptions());
Map<String, String> sendSmsHeaders = sendSmsResponse.getHeaders();
log.info("短验发送响应头:{}", sendSmsHeaders);
SendSmsResponseBody sendSmsBody = sendSmsResponse.getBody();
String sendSmsCode = sendSmsBody.getCode();
log.info("短验发送响应状态码:{}", sendSmsCode);
String sendSmsMsg = sendSmsBody.getMessage();
log.info("短验发送响应信息:{}", sendSmsBody.getMessage());
if (!sendSmsCode.equalsIgnoreCase("OK")) {
log.error("短验发送不成功,sendSmsCode:{},sendSmsMsg:{}", sendSmsCode, sendSmsMsg);
return AjaxResult.error("验证码发送失败");
}
} catch (Exception e) {
log.error("验证码发送失败", e);
return AjaxResult.error("验证码发送失败");
}
log.info("保存验证码信息到缓存");
redisCache.setCacheObject(verifyKey, code, Constants.TEXT_EXPIRATION, TimeUnit.MINUTES);
return AjaxResult.success("验证码已发送", phoneNumber);
}
短验校验流程
/**
* 校验短信验证码
*/
@PostMapping("/checkTextCode")
public AjaxResult checkTextCode(@RequestBody LoginBody loginBody) {
log.info("校验短信验证码 开始");
AjaxResult ajaxResult = authorizeService.checkTextCode(loginBody);
log.info("校验短信验证码 结束");
return ajaxResult;
}
@Override
public AjaxResult checkTextCode(LoginBody loginBody) {
String phoneNumber = loginBody.getPhoneNumber();
if (StringUtils.isEmpty(phoneNumber)) {
log.error("电话号码为空");
return AjaxResult.success("电话号码为空");
}
String textCode = loginBody.getTextCode();
if (StringUtils.isEmpty(textCode)) {
log.error("验证码为空");
return AjaxResult.success("验证码为空");
}
log.info("发送短信的手机号码:{}", phoneNumber);
String verifyKey = CacheConstants.TEXT_CODE_KEY + phoneNumber;
String textCodeInCache = redisCache.getCacheObject(verifyKey);
redisCache.deleteObject(verifyKey);
if (StringUtils.isEmpty(textCode)) {
log.error("缓存中未找到该手机号码对应的验证码");
return AjaxResult.success("验证码已过期,请重新发送");
}
if (!textCode.equalsIgnoreCase(textCodeInCache)) {
log.error("验证码不正确");
return AjaxResult.success("验证码不正确,请重新输入");
}
return AjaxResult.success("验证通过", phoneNumber);
}