SpringBoot實(shí)現(xiàn)短信驗(yàn)證碼校驗(yàn)方法思路詳解
有關(guān)阿里云通信短信服務(wù)驗(yàn)證碼的發(fā)送,請(qǐng)參考我的另一篇文章 Springboot實(shí)現(xiàn)阿里云通信短信服務(wù)有關(guān)短信驗(yàn)證碼的發(fā)送功能
思路
用戶輸入手機(jī)號(hào)后,點(diǎn)擊按鈕獲取驗(yàn)證碼。并設(shè)置冷卻時(shí)間,防止用戶頻繁點(diǎn)擊。
后臺(tái)生成驗(yàn)證碼并發(fā)送到用戶手機(jī)上,根據(jù)驗(yàn)證碼、時(shí)間及一串自定義秘鑰生成MD5值,并將時(shí)間也傳回到前端。
用戶輸入驗(yàn)證碼后,將驗(yàn)證碼和時(shí)間傳到后臺(tái)。后臺(tái)先用當(dāng)前時(shí)間減去前臺(tái)傳過來的時(shí)間驗(yàn)證是否超時(shí)。如果沒有超時(shí),就用用戶輸入的驗(yàn)證碼 + 時(shí)間 + 自定義秘鑰生成MD5值與之前的MD5值比較,如果相等則驗(yàn)證碼校驗(yàn)通過,如果不等則說明驗(yàn)證碼輸入錯(cuò)誤校驗(yàn)失敗。
原理有點(diǎn)像解方程:
xyz經(jīng)過一種不可逆運(yùn)算得到A,將y和A傳給用戶,z后臺(tái)保留,用戶填寫x1后,將x1 y A傳回后臺(tái),后臺(tái)再用x1 y z經(jīng)過不可逆運(yùn)算得到A1,如果A1和A相等,則驗(yàn)證碼校驗(yàn)通過。
前端的實(shí)現(xiàn)
本例基于BootStrap,html代碼中有BootStrap樣式。如果你不想用BootStrap,可以將class樣式去掉。效果如圖所示。
html代碼如下:
<div class="form-group has-feedback"> <input type="tel" class="form-control" id="phone" placeholder="請(qǐng)輸入手機(jī)號(hào)" 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="請(qǐng)輸入驗(yàn)證碼"> </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="免費(fèi)獲取驗(yàn)證碼"> </div> </div> </div> <div class="col-xs-12 pull_center"> <button type="button" class="btn btn-block btn-flat" onclick="validateNum()">驗(yàn)證</button> </div>
js代碼(基于jQuery)
var messageData;
var wait = 120; // 短信驗(yàn)證碼120秒后才可獲取下一個(gè)
/**
* 獲取驗(yàn)證碼
* @param that
*/
function getMsgNum(that) {
var phoneNumber = $('#phone').val();
setButtonStatus(that); // 設(shè)置按鈕倒計(jì)時(shí)
var obj = {
phoneNumber: phoneNumber
};
$.ajax({
url: httpurl + '/sendMsg', // 后臺(tái)短信發(fā)送接口
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("錯(cuò)誤碼:" + data.code + " 錯(cuò)誤信息:" + data.message);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log(XMLHttpRequest.status);
console.log(XMLHttpRequest.readyState);
console.log(textStatus);
}
});
}
/**
* 設(shè)置按鈕狀態(tài)
*/
function setButtonStatus(that) {
if (wait == 0) {
that.removeAttribute("disabled");
that.value="免費(fèi)獲取驗(yàn)證碼";
wait = 60;
} else {
that.setAttribute("disabled", true);
that.value=wait+"秒后可以重新發(fā)送";
wait--;
setTimeout(function() {
setButtonStatus(that)
}, 1000)
}
}
/**
* 注冊(cè)按鈕
*/
function validateNum() {
var data = {
msgNum: inputMsgNum,
tamp: messageData.tamp,
hash: messageData.hash
};
$.ajax({
url: httpurl + '/validateNum', // 驗(yàn)證接口
type: 'POST',
dataType: 'json',
contentType: "application/json",
data: JSON.stringify(data),
async: false, //false 同步
success: function (data) {
//業(yè)務(wù)處理
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log(XMLHttpRequest.status);
console.log(XMLHttpRequest.readyState);
console.log(textStatus);
}
});
}
其中setButtonStatus()方法用于設(shè)置按鈕冷卻狀態(tài)。效果如下圖

后臺(tái)的實(shí)現(xiàn)
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);// 生成隨機(jī)數(shù)
SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
Calendar c = Calendar.getInstance();
c.add(Calendar.MINUTE, 5);
String currentTime = sf.format(c.getTime());// 生成5分鐘后時(shí)間,用戶校驗(yàn)是否過期
sengMsg(); //此處執(zhí)行發(fā)送短信驗(yàn)證碼方法
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時(shí)間返回給前端
}
@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)){
//校驗(yàn)成功
}else {
//驗(yàn)證碼不正確,校驗(yàn)失敗
}
} else {
// 超時(shí)
}
}
總結(jié)
以上所述是小編給大家介紹的SpringBoot實(shí)現(xiàn)短信驗(yàn)證碼校驗(yàn)方法思路詳解,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- SpringBoot 集成Kaptcha實(shí)現(xiàn)驗(yàn)證碼功能實(shí)例詳解
- SpringBoot實(shí)現(xiàn)前端驗(yàn)證碼圖片生成和校驗(yàn)
- Springboot實(shí)現(xiàn)驗(yàn)證碼登錄
- SpringBoot發(fā)送郵箱驗(yàn)證碼功能
- SpringBoot使用郵箱發(fā)送驗(yàn)證碼實(shí)現(xiàn)注冊(cè)功能
- springboot實(shí)現(xiàn)郵箱驗(yàn)證碼功能
- SpringBoot發(fā)送郵件功能 驗(yàn)證碼5分鐘過期
- SpringBoot登錄驗(yàn)證碼實(shí)現(xiàn)過程詳解
- SpringBoot后端驗(yàn)證碼的實(shí)現(xiàn)示例
相關(guān)文章
java中ArrayList和LinkedList的區(qū)別詳解
這篇文章主要介紹了java中ArrayList和LinkedList的區(qū)別詳解,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2021-01-01
SpringCloud?Feign?傳輸Date類型參數(shù)存在誤差的問題
這篇文章主要介紹了SpringCloud?Feign?傳輸Date類型參數(shù)存在誤差的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
KotlinScript構(gòu)建SpringBootStarter保姆級(jí)教程
這篇文章主要為大家介紹了KotlinScript構(gòu)建SpringBootStarter的保姆級(jí)教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
java面試題解LeetCode27二叉樹的鏡像實(shí)例
這篇文章主要為大家介紹了java面試題解LeetCode27二叉樹的鏡像實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
淺談Maven安裝及環(huán)境配置出錯(cuò)的解決辦法
這篇文章主要介紹了淺談Maven安裝及環(huán)境配置出錯(cuò)的解決辦法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
Java微信小程序醫(yī)院掛號(hào)系統(tǒng)
這篇文章主要介紹了基于Java微信小程序醫(yī)院掛號(hào)系統(tǒng),可以實(shí)現(xiàn)遠(yuǎn)程處理事務(wù),遠(yuǎn)程提交工作和隨時(shí)追蹤工作的狀態(tài),文中提供了解決思路和部分實(shí)現(xiàn)代碼,需要的朋友可以參考下2023-03-03
使用springboot時(shí),解決@Scheduled定時(shí)器遇到的問題
這篇文章主要介紹了使用springboot時(shí),解決@Scheduled定時(shí)器遇到的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11

