欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-07-10 21:42:33
近期公司有个需求,要求使用短信验证码登录,取代原来的图片验证码方式,在此记录一下我的实现方法,希望对你有所帮助公司需求:目前只有账号和验证码方式验证登录,按照公司网络安全统一部署,要求所有公网系统都需要动态双因子认证改造方案:此ULR增加登录短信验证,取代验证码验证对于此需求,思路就是点了"发送验证码"按钮后,前台开始倒计时,后台随机生成一个6位数的验证码记录一下当前的时间戳(用来校验验证码是否失效,根据业务情况的不同设置不同的失效时间,我这里是5分钟内有效),将发送的验证码和时间戳返回前...

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

  • 公司需求:目前只有账号和验证码方式验证登录,按照公司网络安全统一部署,要求所有公网系统都需要动态双因子认证
  • 改造方案:此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