SpringBoot实现短信验证码校验方法思路详解
程序员文章站
2024-02-23 12:38:22
有关阿里云通信短信服务验证码的发送,请参考我的另一篇文章 springboot实现阿里云通信短信服务有关短信验证码的发送功能
思路
用户输入手机...
有关阿里云通信短信服务验证码的发送,请参考我的另一篇文章 springboot实现阿里云通信短信服务有关短信验证码的发送功能
思路
用户输入手机号后,点击按钮获取验证码。并设置冷却时间,防止用户频繁点击。
后台生成验证码并发送到用户手机上,根据验证码、时间及一串自定义秘钥生成md5值,并将时间也传回到前端。
用户输入验证码后,将验证码和时间传到后台。后台先用当前时间减去前台传过来的时间验证是否超时。如果没有超时,就用用户输入的验证码 + 时间 + 自定义秘钥生成md5值与之前的md5值比较,如果相等则验证码校验通过,如果不等则说明验证码输入错误校验失败。
原理有点像解方程:
xyz经过一种不可逆运算得到a,将y和a传给用户,z后台保留,用户填写x1后,将x1 y a传回后台,后台再用x1 y z经过不可逆运算得到a1,如果a1和a相等,则验证码校验通过。
前端的实现
本例基于bootstrap,html代码中有bootstrap样式。如果你不想用bootstrap,可以将class样式去掉。效果如图所示。
html代码如下:
<div class="form-group has-feedback"> <input type="tel" class="form-control" id="phone" placeholder="请输入手机号" maxlength=11> <span class="glyphicon glyphicon-earphone form-control-feedback"></span> </div> <div class="row"> <div class="col-xs-6 pull_left"> <div class="form-group"> <input class="form-control" id="msg_num" placeholder="请输入验证码"> </div> </div> <div class="col-xs-6 pull_center"> <div class="form-group"> <input type="button" class="btn btn-block btn-flat" id="verify_refresh" onclick="getmsgnum(this)" value="免费获取验证码"> </div> </div> </div> <div class="col-xs-12 pull_center"> <button type="button" class="btn btn-block btn-flat" onclick="validatenum()">验证</button> </div>
js代码(基于jquery)
var messagedata; var wait = 120; // 短信验证码120秒后才可获取下一个 /** * 获取验证码 * @param that */ function getmsgnum(that) { var phonenumber = $('#phone').val(); setbuttonstatus(that); // 设置按钮倒计时 var obj = { phonenumber: phonenumber }; $.ajax({ url: httpurl + '/sendmsg', // 后台短信发送接口 type: 'post', datatype: 'json', contenttype: "application/json", async: false, //false 同步 data: json.stringify(obj), xhrfields: { withcredentials: true }, success: function (result) { if(result.code == '200') { messagedata = result.data; }else { alert("错误码:" + data.code + " 错误信息:" + data.message); } }, error: function (xmlhttprequest, textstatus, errorthrown) { console.log(xmlhttprequest.status); console.log(xmlhttprequest.readystate); console.log(textstatus); } }); } /** * 设置按钮状态 */ function setbuttonstatus(that) { if (wait == 0) { that.removeattribute("disabled"); that.value="免费获取验证码"; wait = 60; } else { that.setattribute("disabled", true); that.value=wait+"秒后可以重新发送"; wait--; settimeout(function() { setbuttonstatus(that) }, 1000) } } /** * 注册按钮 */ function validatenum() { var data = { msgnum: inputmsgnum, tamp: messagedata.tamp, hash: messagedata.hash }; $.ajax({ url: httpurl + '/validatenum', // 验证接口 type: 'post', datatype: 'json', contenttype: "application/json", data: json.stringify(data), async: false, //false 同步 success: function (data) { //业务处理 }, error: function (xmlhttprequest, textstatus, errorthrown) { console.log(xmlhttprequest.status); console.log(xmlhttprequest.readystate); console.log(textstatus); } }); }
其中setbuttonstatus()方法用于设置按钮冷却状态。效果如下图
后台的实现
private static final string key = "abc123"; // key为自定义秘钥 @requestmapping(value = "/sendmsg", method = requestmethod.post, headers = "accept=application/json") public map<string, object> sendmsg(@requestbody map<string,object> requestmap) { string phonenumber = requestmap.get("phonenumber").tostring(); string randomnum = commonutils.createrandomnum(6);// 生成随机数 simpledateformat sf = new simpledateformat("yyyymmddhhmmss"); calendar c = calendar.getinstance(); c.add(calendar.minute, 5); string currenttime = sf.format(c.gettime());// 生成5分钟后时间,用户校验是否过期 sengmsg(); //此处执行发送短信验证码方法 string hash = md5utils.getmd5code(key + "@" + currenttime + "@" + randomnum);//生成md5值 map<string, object> resultmap = new hashmap<>(); resultmap.put("hash", hash); resultmap.put("tamp", currenttime); return resultmap; //将hash值和tamp时间返回给前端 } @requestmapping(value = "/validatenum", method = requestmethod.post, headers = "accept=application/json") public map<string, object> validatenum(@requestbody map<string,object> requestmap) { string requesthash = requestmap.get("hash").tostring(); string tamp = requestmap.get("tamp").tostring(); string msgnum = requestmap.get("msgnum").tostring(); string hash = md5utils.getmd5code(key + "@" + tamp + "@" + msgnum); if (tamp.compareto(currenttime) > 0) { if (hash.equalsignorecase(requesthash)){ //校验成功 }else { //验证码不正确,校验失败 } } else { // 超时 } }
总结
以上所述是小编给大家介绍的springboot实现短信验证码校验方法思路详解,希望对大家有所帮助