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