SpringBoot實現短信驗證碼校驗方法思路詳解
有關阿里云通信短信服務驗證碼的發(fā)送,請參考我的另一篇文章 Springboot實現阿里云通信短信服務有關短信驗證碼的發(fā)送功能
思路
用戶輸入手機號后,點擊按鈕獲取驗證碼。并設置冷卻時間,防止用戶頻繁點擊。
后臺生成驗證碼并發(fā)送到用戶手機上,根據驗證碼、時間及一串自定義秘鑰生成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', // 后臺短信發(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("錯誤碼:" + data.code + " 錯誤信息:" + data.message); } }, error: function (XMLHttpRequest, textStatus, errorThrown) { console.log(XMLHttpRequest.status); console.log(XMLHttpRequest.readyState); console.log(textStatus); } }); } /** * 設置按鈕狀態(tài) */ function setButtonStatus(that) { if (wait == 0) { that.removeAttribute("disabled"); that.value="免費獲取驗證碼"; wait = 60; } else { that.setAttribute("disabled", true); that.value=wait+"秒后可以重新發(fā)送"; 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) { //業(yè)務處理 }, error: function (XMLHttpRequest, textStatus, errorThrown) { console.log(XMLHttpRequest.status); console.log(XMLHttpRequest.readyState); console.log(textStatus); } }); }
其中setButtonStatus()方法用于設置按鈕冷卻狀態(tài)。效果如下圖
后臺的實現
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(); //此處執(zhí)行發(fā)送短信驗證碼方法 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實現短信驗證碼校驗方法思路詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!
相關文章
Java獲取HttpServletRequest的三種方法詳解
這篇文章主要介紹了Java獲取HttpServletRequest的三種方法詳解,是一個接口,全限定名稱為Jakarta.Serclet.http.HttpServletRequest2023-11-11
HttpServletRequest接口是Servlet規(guī)范的一員,需要的朋友可以參考下Java8特性之用Stream流代替For循環(huán)操作詳解
這篇文章主要介紹了Stream流代替For循環(huán)進行輸出,這樣可以使代碼更簡潔,希望對大家有所幫助。一起跟隨小編過來看看吧2021-09-09