当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 系统登录页面短信验证码方式登录实现

系统登录页面短信验证码方式登录实现

2020年07月14日  | 移动技术网IT编程  | 我要评论

近期公司有个需求,要求使用短信验证码登录,取代原来的图片验证码方式,在此记录一下我的实现方法,希望对你有所帮助

  • 公司需求:目前只有账号和验证码方式验证登录,按照公司网络安全统一部署,要求所有公网系统都需要动态双因子认证
  • 改造方案:此ULR增加登录短信验证,取代验证码验证

对于此需求,思路就是

  1. 点了"发送验证码"按钮后,前台开始倒计时,后台随机生成一个6位数的验证码
  2. 记录一下当前的时间戳(用来校验验证码是否失效,根据业务情况的不同设置不同的失效时间,我这里是5分钟内有效),将发送的验证码和时间戳返回前台
  3. 待用户填写的同时,实时检查用户填写的验证码是否正确,是否超时
  4. 待用户填写正确的验证码后,放行登录请求

下面就是具体实现:

HTML:

<div class="Rbox absulute">

    <form class="loginform form-signin" id="loginForm"  action="${ctx}/login" method="post" name="loginForm">
        <div   id="messageBox" class="alert alert-error ${empty message ? 'hideErr' : 'showErr'}" style=""><button data-dismiss="alert" class="close">×</button>
            <label id="loginError" class="error">${message}</label>
        </div>
        <div class="radius shadow mt10"><input id="un" type="text" placeholder="用户名" name="username" class="required" autocomplete="off"/><img src="../imgs/user.png"></div>
        <div class="mt20 radius shadow "><input id="pw" type="password" placeholder="密码"  name="password" class="required" maxlength="20" autocomplete="off"/><img src="../imgs/password.png" ></div>
        <div class="mt20 radius shadow "><input id="ph" type="text" placeholder="手机号"  name="phone" class="required" maxlength="11" autocomplete="off" style="width: 87%"/>
            <img src="../imgs/phone.png" style="width: 21px;height: 21px;padding-right: 2px"></div>
        <div class="mt20 radius shadow "><input id="vc" type="text" placeholder="验证码"  name="verifyCode" class="required" maxlength="6" autocomplete="off" style="width:56%;display: inline-block;"/>
            <input id="getVcBtn" class="gradientbtn btn1 sendVerifyCode" type="button" style="display: inline-block;width: 43%;margin-right: 1px;margin-top: 1px;float:right" value="获 取" onclick="sendVarCode();" /> </div>
        <div class="mt10 remeberUser "><input type="checkbox" id="rememberMe" name="rememberMe" ${rememberMe ? 'checked' : ''}/> <span >记住我</span></div>
        <div class="mt10"><input id="loginBtn" class="gradientbtn  btn1" type="submit" value="登 录" /></div>
        <div class="mt10"><input id="createTime" type="hidden" value="200000" name="createTime" style="display: none"/></div>
        <div class="mt10"><input id="sendedVarCode" type="hidden" value="100000" name="sendedVarCode" style="display: none"/></div>
        <input type="hidden" name="csrftoken" value="${csrftoken}"/>
    </form>

</div>

JS:

<script language="javascript">

    //短信验证码倒计时
    var countdownHandler = function(){
        var $button = $("#getVcBtn");
        var number = 60;
        var flag=1;
        var countdown = function(){
            // debugger
            if (number == 0) {
                $button.attr("disabled",false);
                $button.val("发送验证码");
                $button.css({"background":"-webkit-gradient(linear, left top, right bottom, from(#e05b8d), to(#a94e97))","cursor":"pointer"});
                number = 60;
                flag=0;
                return;
            } else if( flag==1 ){
                $button.attr("disabled",true);
                $button.css({"background":"#a29e9e","cursor":"default"});
                $button.val(number + "秒后重新获取");
                number--;
            }
        };
        setInterval(countdown,1000);
    }

    //校验手机号格式
    function chackPhone(phone){
        re = /^1[3456789]\d{9}$/
        if (re.test(phone)) {
            return true;
        } else {
            return false;
        }
    }
    //发送短信验证码
    function sendVarCode(){
        var $mobile = $("input[name=phone]");//用户填写的手机号
        var $createTime = $("input[id=createTime]");//这个是给用户发送验证码时的时间戳
        var $sendedVarCode = $("input[id=sendedVarCode]");//这个用来记录给用户发送的验证码
        var data = {};
        data.mobile = $.trim($mobile.val());
        if( data.mobile == '' ) {
            alert('请输入手机号码!');
            return;
        }else if( chackPhone(data.mobile)==false ){
            alert('请输入正确的手机号!');
            return;
        }

        $.ajax({
            url: "${ctx}/sendVarSms",
            //async: true,
            type: 'POST',
            data: data,
            success: function (data) {
                const data1 = JSON.parse(data);
                if(data1.result=="success"){
                    countdownHandler();
                    $createTime.val(data1.sendData.createTime);
                    $sendedVarCode.val(data1.sendData.sendedVarCode);
                    return ;
                }else{
                    console.error("验证码发送失败,请联系管理员!")
                }
            }
        });

    }

    //校验表单
    $(document).ready(function() {
        $("#loginForm").validate({
            rules: {
                password: {rangelength:[6,20]},
                phone: {rangelength:[11,11]},
                verifyCode:  {
                    required: true,
                    remote: {
                        url: "${pageContext.request.contextPath}/a/checkVerifyCode",
                        type: "POST",
                        data: {
                            verifyCode:function(){return $("input[name=verifyCode]").val()},
                            createTime:function(){return $("input[id=createTime]").val()},
                            sendedVarCode:function(){return $("input[id=sendedVarCode]").val()}
                        }
                    }

                },
            },
            messages: {
                username: {required: "请填写用户名."},
                password: {required: "请填写密码.",rangelength:"密码至少6位,最多20位."},
                phone: {required: "请输入手机号.",rangelength:"手机号必须为11位."},
                verifyCode: {required: "请填写验证码.",remote:"验证码错误."}
            },
            errorLabelContainer: "#messageBox",
            errorPlacement: function(error, element) {
                error.appendTo($("#loginError").parent());
            },
            submitHandler:function(form){
                var pw = encryptByDES($("#pw").val(),"abc123.*abc123.*abc123.*abc123.*");
                $("#pw").val(pw);
                document.loginForm.submit();  //fm为form表单name
            }
        });


</script>

JAVA:

/**
	 * 发送短信验证码
	 */
	@RequestMapping(value = "${adminPath}/sendVarSms" , method = RequestMethod.POST)
	@ResponseBody
	public String sendVarSms(HttpServletRequest request, HttpServletResponse response, Model model) {
		Map<String, Object> map = new HashMap<String,Object>();
		try {
			String mobile = request.getParameter("mobile");
			JSONObject json = null;
			//生成6位验证码
			String verifyCode = String.valueOf(new Random().nextInt(899999) + 100000);
			String message="您的验证码为:" + verifyCode + " ,您正在使用短信验证码登录,5分钟内有效,感谢您的使用!【XXX服务平台】";
			String result = custDataManageService.sendMessage(mobile, message);
			if(result != "success"){//发送短信失败
				map.put("result","fail");
			}
			json = new JSONObject();
			json.put("mobile", mobile);
			json.put("sendedVarCode", verifyCode);
			json.put("createTime", System.currentTimeMillis());
			map.put("result","success");
			map.put("sendData", json);
			return JSONUtil.toJson(map);
		} catch (Exception e) {
			e.printStackTrace();
			map.put("result","fail");
		}
		return JSONUtil.toJson(map);
	}
	/**
	 * 校验短信验证码是否正确以及是否超时
	 */
	@RequestMapping(value = "${adminPath}/checkVerifyCode" , method = RequestMethod.POST)
	public void checkVerifyCode(HttpServletRequest request, HttpServletResponse response, Model model) {
		try {
			response.setContentType("text/html;charset=utf-8");
			PrintWriter out = response.getWriter();
			String verifyCode = request.getParameter("verifyCode");
			String sendedVarCode = request.getParameter("sendedVarCode");
			String createTime = request.getParameter("createTime");
			long nowTime = System.currentTimeMillis();
			long timeDiff = (nowTime - Long.parseLong(createTime)) / 1000 / 60;
			if (verifyCode.equals(sendedVarCode) && timeDiff < 5) {
				out.print(true);
			} else {
				out.print(false);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

由于我们公司本身就具有发送短信的能力,所以发送短信验证码的方法这里就略了,你们可以调用一些短信发送平台的api,实现发送短信的功能,网上很多,这里不再赘述

至此,短信验证码方式登录系统实现完成!

本文地址:https://blog.csdn.net/zhen_hero/article/details/107318478

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网