简述短信验证码登录功能实现

最近做了一个系统的短信验证与登录的功能,这里简述一下实现方法。

前端方面,像众多系统一样,jsp页面上有两个输入栏,一栏输入手机号,一栏输入验证码,输入验证码邮编是点击发送验证码,点击之后开始60s倒计时。且用js写好对手机号规则验证的正则表达式。js还有两个核心方法,一个是点击发送验证码时调用后端controller中的messageSend方法,一个是点击提交时调用后端controller中的checkVcode方法。核心代码如下:

$('.hmac').on('click',function(){
		if(!/^(13[0-9]|15[012356789]|17[0-9]|18[0-9]|14[57])[0-9]{8}|(170[059])[0-9]{6}$/i.test($('#phone').val())){
			layer.msg("请输入正确的手机号");
			return ;
	   	}
			var codeflag = 60;
			if(phoneflag == 1&&codeflag==60){
				var timeflag = setInterval(function(){
				    codeflag--;
					if(codeflag>0){
						$('.hmac').val('重新发送'+codeflag+'s');
						$('.hmac').css({'color':'#99897A','border':'1px solid #99897A'});
						$('.hmac').attr('disabled','disabled');
				    }else{
						codeflag=60;
						$('.hmac').val('获取验证码');
						$('.hmac').css({'color':'#68371D'});
						$('.hmac').removeAttr('disabled');
						clearInterval(timeflag);
				}
			},1000);
			BaseUtils.ajaxAction_nomsg("login/messageSend", {
				phone:$('#phone').val()
			}, {
				success: function(data) {
					//alert(data);
				}, error : function(data) {
					layer.msg(data.message);
				}
			});
	}
	})
	
	function checkUser(){
		var phone = $('#phone').val();
		var vcode = $('#vcode').val()
		
		if(phone == ""  ){
			layer.msg("请输入手机号");
			return false;
		}
		if(vcode == ""  ){
			layer.msg("请输入验证码");
		 	return false;
		}
		
		if(typeof(phone)!="undefined"&&typeof(vcode)!="undefined"){
			BaseUtils.ajaxAction_nomsg("login/checkVcode", {
				phone:phone,
				vcode:vcode
			}, {
				success: function(data) {
					$("form").submit();
				}, error : function(data) {
					layer.msg('验证码错误');
				}
			},
			false);
		}else{
	 		layer.msg('登录用户信息错误');
	 		return false;
		}
	}

后端方面,购买一个发短信的第三方平台接口,调用其接口即可对相应手机号进行短信发送。查看相关接口文档,得到可以使用来发短信的id,用户名和密码。用户输入的电话可通过前端jsp的form表单提交至后端,后端控制器使用request.getParameter得到这个字段,再将以文档规范调用短信发送接口,即可实现短信发送功能。核心代码如下:

//发送短信
	@RequestMapping(value = "messageSend")
	public void messageSend(HttpServletRequest request, HttpServletResponse response) throws IOException{ 
		
		String tel = request.getParameter("phone");
		JSONObject ret = new JSONObject();
		try{
			if(!StringUtil.isEmpty(tel)){
				User u = this.getUser(request.getSession());
				WeixinUserInfo oldparam = new WeixinUserInfo();
				oldparam.setPhone(tel);
				WeixinUserInfo localWeixinUserInfo=wxPublicService.getUserInfo(oldparam);
				if(u!=null&&localWeixinUserInfo!=null&&!localWeixinUserInfo.getOpenId().equals(u.getOpenId())){
					log.info("checkVcode fail and phone is "+ tel + " user exsit "+localWeixinUserInfo.getOpenId());
					ret.put("success", false);
					ret.put("message", "电话号码已绑定其他微信");
				}else{
					//生成验证码
					Integer code = RandomGUIDUtil.getdentifCode();
					
					String sTotalString = HttpRequest.sendPost(" ","action=send&userid= &account= &password= &mobile=" + tel +"&content=验证码为" + code + ",请勿告知其他人,有效期为1分钟。&sendTime=&extno=");

					RedisClient.setObject("vcode_"+tel,100,code);

					log.info("checkVeryCode: very_code="+sTotalString+" code="+code);
					//ret.put("vcode", code);
					ret.put("success", true);
				}
			}else{
				ret.put("message", "手机号不能为空");
				ret.put("success", false);
			}
		} catch (Exception e) {
        	e.printStackTrace();
        	ret.put("success", false);
        	ret.put("message", e.getMessage());
        	log.error("messageSend error: "+e.getMessage());
        }
		writeJSON(response,  ret.toString());
	}

验证用户输入的验证码与上方法类似,将用户输入的验证码提交到后端进行比对,根据对比结果返回不同的ModelAndView跳转至不同的页面,不过在若前端进行验证码的比对可能会减小对服务器的压力。

//发送短信
	@RequestMapping(value = "checkVcode")
	public void checkVcode(HttpServletRequest request, HttpServletResponse response) throws IOException{ 
		
		String phone = request.getParameter("phone");
		String vcode = request.getParameter("vcode");
		String userName=request.getParameter("userName");
		
		User u = this.getUser(request.getSession());
		
		JSONObject ret = new JSONObject();
		try{
			if(!StringUtil.isEmpty(phone)&&!StringUtil.isEmpty(vcode)){
				String vcodeNum=(String) RedisClient.get("vcode_"+phone);
				if((vcodeNum!=null&&vcodeNum.equals(vcode))||vcode.equals(ZongsConfig.getVal("phone.code"))){
					WeixinUserInfo oldparam = new WeixinUserInfo();
					oldparam.setPhone(phone);
					WeixinUserInfo localWeixinUserInfo=wxPublicService.getUserInfo(oldparam);

					if(localWeixinUserInfo!=null&&!localWeixinUserInfo.getOpenId().equals(u.getOpenId())){
						log.info("checkVcode fail and phone is "+ phone + " user exsit "+localWeixinUserInfo.getOpenId());
						ret.put("success", false);
						ret.put("message", "电话号码已被使用");
					}else{
						//CommonConstant

						u.setRealName(userName);
						u.setPhone(phone);
						WeixinUserInfo param = new WeixinUserInfo();
						param.setOpenId(u.getOpenId());
						param.setPhone(phone);
						param.setRealName(userName);
						wxPublicService.updateUserInfo(param);
									
						//String userInfo = HttpRequest.sendGet(CommonConstant.BACK_SYSTEM_URL+"/jeeplus/a/weixinuser/saveUser","phone="+phone);
						//log.info("create info :"+userInfo);
						log.info("checkVcode success and phone is "+ phone);
						ret.put("success", true);
					}
				}else{
					ret.put("success", false);
					ret.put("message", "验证码错误");
					log.info("checkVcode fail and phone is "+ phone+" vcode is "+vcode +" vcodeNum is "+vcodeNum);
				}
			}else{
				ret.put("success", false);
				ret.put("message", "手机号和验证码不能为空");
				log.info("checkVcode fail and phone is "+ phone+" vcode is "+vcode);
			}
		} catch (Exception e) {
        	e.printStackTrace();
        	ret.put("success", false);
        	ret.put("message", e.getMessage());
        	log.error("messageSend error: "+e.getMessage());
        }
		writeJSON(response,  ret.toString());
	}

本系统是基于spring mvc + mybatis的基础上进行代码编写的,相关配置及第三方类库的引入这里就不做赘述了。

你可能感兴趣的:(工作项目笔记)