短信验证注册
短信验证码发送操作逻辑:
1>点击获取验证码按钮发送短信到注册那个手机号码上
2>注册手机收到短信验证码,并输入
3>低级注册携带短信验证码,判断验证码是否正确
4>将code缓存到redis对象,并设置过期时间(这里key为手机号,value为验证码)
主要思考问题:项目中的key怎么管理 —>定义一个常量类进行统一管理
前端发送异步请求
//短信发送
$('.vcode-send').click(function () {
if ($(this).hasClass('disabled')) {
} else {
var self = $(this);
var count = 10;
self.addClass('disabled')
self.text(count + '秒后重新获取')
var timer = setInterval(function () {
count--;
if (count > 0) {
self.text(count + '秒后重新获取');
} else {
clearInterval(timer)
self.text('重新获取验证码')
self.removeClass("disabled");
}
}, 1000);
var phone = $("#phone").val();
$.get(domainUrl + "/users/sendVerifyCode", {phone:phone}, function (data) {
console.log(data);
if(data.code == 200){
popup("发送成功")
}else{
popup(data.msg);
}
})
}
});
后端数据处理
//controller类
@GetMapping("/sendVerifyCode")
public Object sendVerifyCode(String phone){
userInfoService.sendVerifyCode(phone);
return JsonResult.success();
}
//接口
/**
* 发送短信验证码
* @param phone
*/
void sendVerifyCode(String phone);
//实现类
@Override
public void sendVerifyCode(String phone) {
//创建4位数的验证码(随机,唯一)
String code = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 4);
//拼接短信验证码提示信息
StringBuilder sb = new StringBuilder(50);
sb.append("您注册的验证码是:").append(code).append(",请在").append(Consts.VERIFY_CODE_VAI_TIME).append("分钟内提交");
//项目中模拟发短信
System.out.println(sb);
//真实发送短信本质就是使用java发起http请求即可
//RestTemplate用于发起http请求的工具类
/* RestTemplate template = new RestTemplate();
String url = "https://way.jd.com/chuangxin/dxjk?mobile={1}&content=【靓仔】{2}&appkey={3}";
String rep = template.getForObject(url, String.class, phone, sb.toString(), "81160ff2102302361058123544194785");
System.out.println(rep);*/
//缓存验证码
userInfoRedisService.setVerifyCode(phone, code);
}
/**
* 生成短信验证码
* @param phone
* @param code
*/
void setVerifyCode(String phone,String code);
@Override
public void setVerifyCode(String phone, String code) {
//key设置原则:可读性,唯一性,灵活性,时效性
String key = RedisKeys.VERIFY_CODE.join(phone);
//把key存入缓存中,设置有效时间为5分钟
redisTemplate.opsForValue().set(key, code,RedisKeys.VERIFY_CODE.getTime(),TimeUnit.SECONDS);
}
枚举类特点
1>枚举类的构造器是私有的
2>枚举类当定义完成之后,实例的个数固定
3>其他操作跟普通类一样
//EsdisKeys枚举类
//短信验证
VERIFY_CODE("verify_code",Consts.VERIFY_CODE_VAI_TIME *60L),
//前缀
private String prefix;
private Long time;
private RedisKeys(String prefix,Long time){
this.prefix = prefix;
this.time = time;
}
//前缀拼接
public String join(String... values){
StringBuilder sb = new StringBuilder(20);
sb.append(this.prefix);
for (String value : values) {
sb.append(":").append(value);
}
return sb.toString();
}
常量类设计
/**
* 系统常量
*/
public class Consts {
//验证码有效时间
public static final int VERIFY_CODE_VAI_TIME = 5; //单位分
}