登陆时短信验证码的原理和实现逻辑
登陆时需要发送短信验证码或者其他的验证方式来校验是否是本人操作,达到安全性的目的。本文主要以个人思考的实现方式做讲解,来看看常用的短信验证码的前台界面的实现。效果如图:
点击获取验证码时,倒计时,暂时设定倒计时的时间为180秒,
思路:
- 当点击【获取验证码】按钮时,发送请求到后台,根据自己的规则生成4位,6位或者8位数字,在用一个标识作为key,将随机数存到session中,我这里是用用户名作为key。
- 发送验证码成功之后,前端开始倒计时,当倒计时的时间 = 0时,发送请求到后端,将用户名作为参数传人,从用户名在session查找,得到发送验证码时保存到session中的随机数,然后从session中清除。
- 假如在倒计时中,用户已经输入了验证码,此时停止倒计时,将输入的验证码和用户名作为入参,传人后台,从session保存的验证码做比对,校验是否正确,
- 假如验证码正确,将倒计时框置为不可用,假如错误,停止倒计时,提示【验证码有误,请重新输入】。
-
验证码正确,提交表单是定义一个标识,可以提交表单
资源网站大全 https://55wd.com 我的007办公资源网站 https://www.wode007.com
代码实现如下:
前端代码
发送验证码:
function getVlidCode(){ var username = $("#username").val();//将用户名作为session存储的key if (flagT){ $.ajax({ type:"GET", async: false, data:"username="+username, url:projectName+"/userAction/getVerifYCode.do", success:function(date){ if (date == 1) { chengeviyfValue(); } } }); } }
定时器,每1000毫秒执行一次:
function chengeviyfValue(){ if ( flag ){ $("#getVerifYCodeNum").text("剩余("+totalNum+")秒"); var username = $("input[name='username']").val(); if (totalNum == 0) {//时间到了 没有值,清空session中保存的验证码 document.getElementById('getVerifYCodeNum').innerhtml = "重新发送"; $.ajax({ type:"GET", async: false, data:"username="+username, url:projectName+"/userAction/removeVerifYCode.do", success:function(date){ Ext.Msg.alert('提示!', '验证码已失效,请重新发送!'); } }); totalNum = 180; flagT = true; return; }else { flagT = false;//当totalNum的值不等于0时,不让在点击发送按钮 } totalNum--; setTimeout('chengeviyfValue()',1000); } }
校验输入验证码是否正确:
function removeVlidCode(){ var vildCode = $(" input[ name='vildCode'] ").val(); var username = $("input[name='username']").val(); if ("" != vildCode && null != vildCode) { $.ajax({ type:"GET", async: false, data:"vildCode="+vildCode+"&username="+username, url:projectName+"/userAction/vlidCodeNum.do", success:function(date){ if (date == "0") { Ext.Msg.alert('提示!', '验证码错误,请重新发送!'); document.getElementById('getVerifYCodeNum').innerhtml = "重新获取"; document.getElementById('getVerifYCodeNum').style.color = "#1497DA" flagT = true; flag = false;//当totalNum = 0时,不让进chengeviyfValue()中totalNum = 0 的判断 totalNum = 0; }else { totalNum = 0; document.getElementById('getVerifYCodeNum').innerhtml = "获取验证码"; flagT = false; flag = false;// document.getElementById('getVerifYCodeNum').style.color = "#D0D0D0" } } }); } }
后端代码:
调用短信发送的功能,没法实现,暂时使用发送邮件的功能代替:
@RequestMapping("userAction/getVerifYCode") public void getVerifYCode(HttpServletRequest request,HttpServletResponse response) throws IOException{ String username = request.getParameter("username"); HttpSession session = request.getSession(); //String bit4Rand = CommonUtils.get4HibitRandom(); String bit4Rand = "12345678";//先写死 session.setAttribute(username, bit4Rand); logger.error("[存入的验证码和key] key:"+username+" bit4Rand:"+bit4Rand); // TODO:调用下发验证码的邮件 UserModel um = userService.findUserInfoByUsername(username); String email = um.getEmail(); String host = "smtp.qq.com";//服务器 String subject = "个人项目登陆时验证码"; String content = "<\n>"+bit4Rand+"<\n>"; String from = "@qq.com"; String pwd = ""; int result = SendEmailUtil.sendEmail(host, from, from, pwd, email, subject, content); // int result = 1; response.getWriter().print(result); }
校验验证码是否正确:
@RequestMapping("userAction/vlidCodeNum") public void vlidCodeNum(HttpServletRequest request,HttpServletResponse response) throws IOException{ String vildCode = request.getParameter("vildCode"); String username = request.getParameter("username"); logger.error("[校验验证码时出入的值]:vildCode:"+vildCode+" username:"+username); HttpSession session = request.getSession(); String vildCodeTwo = (String)session.getAttribute(username); logger.error("[清除验证码从session中]"+vildCodeTwo); if (CommonUtils.isNotEmpty(vildCodeTwo) && vildCode.equals(vildCodeTwo)) { response.getWriter().print("1"); }else { response.getWriter().print("0"); } }
到此验证码的实现都已全部实现。