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实现短信验证码校验方法思路详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!

以上是 SpringBoot实现短信验证码校验方法思路详解 的全部内容, 来源链接: utcz.com/p/214330.html

回到顶部