基于登录注册用ajax实现手机验证码功能


这几天做的项目接触到了用手机验证码完成一些功能,例如登录、注册、以及修改手机号码,想把流程总结出来分享给大家

基于登录发送验证码

操作手机号
登录非空、格式正确、已注册

先用ajax获取框输入的手机号码提交到controller处理,部分jsp代码如下

<input type="hidden" id="u-name-reg-first" value="0" /><!--第一次输入的号码-->
<input type="text" name="key" placeholder="手机号" value=''/>
<a type="button" onclick="sendPhoneCodelogin()" titlelogin="登陆">登陆</a>

第一个框中用于双重验证号码,在点击发送信息时将第二个框中输入的号码赋值
给它,防止发送信息后改动号码
js中代码:

		/**
		* 发送手机验证码
		*/
		function sendPhoneCode() {
		 var mobileVal=$("#u-name-reg").val();//输入的号码
		 var pageFrom = "phoneLogin";//页面来源
		 $("#u-name-reg-first").val(mobileVal);//给第一次号码赋值
		 $.ajax({
		     url:baselocation+'/login/ajax/sendPhoneMsg',
		     type:'post',
		     dataType:'json',
		     data:{
		         "mobileVal":mobileVal,
		         "pageFrom":pageFrom
		     },
		     success:function(result){
		         if(result.success==true){
		             layer.msg(result.message, {icon: 1, shift: 6});
		             var timeTicket;
		             var timeNum = 60;
		             clearInterval(timeTicket);
		             /*当点击获取验证码后设置60秒计时不可点击*/
		             timeTicket = setInterval(function () {
		                 if (timeNum>1){
		                     timeNum--;
		                     /*设置按钮不可点击*/
		                     $(".mobile-yz-btn").addClass("mobile-yz-btn-no");
		                     $(".mobile-yz-btn").attr("onclick","");
		                     $(".mobile-yz-btn").text(timeNum+"秒后重新获取");
		                 }else if (timeNum==1){
		                     $(".mobile-yz-btn").text("点击获取验证码");
		                     $(".mobile-yz-btn").attr("onclick","sendPhoneRegister()");
		                     $(".mobile-yz-btn").removeClass("mobile-yz-btn-no");
		                     timeNum = 60;
		                     clearInterval(timeTicket);
		                     //刷新验证码
		                     $(".js-verify-refresh.c-green").click();
		                 }
		             },1000);
		          }else{
		             layer.msg(result.message, {icon: 5, shift: 6});
		         }
		     }
		 })
		}

消息成功发送后,提交按钮的文本框显示倒计时时间,每隔一秒触发一次事件,60秒后计时结束
在conreoller中:

//发送手机验证码
@RequestMapping("/login/ajax/sendPhoneMsg")
@ResponseBody
	public Map<String,Object> sendPhoneMsg(HttpServletRequest request) throws ClientException {
		 Map<String,Object> json;
		   //获取手机号
		   String mobile=request.getParameter("mobileVal");
		   if(StringUtils.isEmpty(mobile)){
		       json = this.setJson(false,"号码不能为空", null);
		       return json;
		   }
		   if(!WebUtils.checkMobile(mobile)){
		       json = this.setJson(false, "号码格式错误", null);
		       return json;
		   }
		   //获取页面来源
		   String pageFrom=request.getParameter("pageFrom");
		   if(pageFrom!=null){
		       if(pageFrom.equals("register")){
	                String userName = request.getParameter("nameVal");
	                if(userService.checkUsername(userName)){
	                    json = this.setJson(false,"该用户名已注册", null);
	                    return json;
	                }
	                if(userService.checkMobile(mobile)){
	                    json = this.setJson(false,"该号码已注册", null);
	                    return json;
	                }
           	   }
		       if(pageFrom.equals("phoneLogin")){
		           if(!userService.checkMobile(mobile)){
		               json = this.setJson(false,"该号码未注册", null);
		               return json;
		           }
		       }
		   }
		   json=userService.sendMobileCode(mobile,"_mobileCodeNum");
		   return json;
	}

进行号码判空和格式处理,同时根据pageFrom参数获取页面来源,根据“登录”或“注册”页面进行号码判断。若不符合要求则无法发送信息;若通过则调用sendMobileCode方法进行信息发送

	@Override
	public Map<String, Object> sendMobileCode( String mobile, String cachePostfix) 				throws ClientException {

		Map<String, Object> json = new HashMap<String, Object>();
		String mobileCodeNum = "";
		//获得验证码
		mobileCodeNum = WebUtils.getRandomNum(4);//随机验证码4为数
		//先删除之前的验证码缓存
		String usedMobileCodeNum = (String) cache.get(mobile+"_mobileCodeNum");
		cache.remove(usedMobileCodeNum);
		//将验证码存入缓存
		cache.set(mobile + cachePostfix, mobileCodeNum, 300);
		SendSmsResponse sendSmsResponse = sendSms(mobile, mobileCodeNum);
		if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
			//请求成功
			json.put("success", Boolean.valueOf(true));
			json.put("message", "短信发送成功");
			json.put("entity", null);
			return json;
		}
		json.put("success", Boolean.valueOf(false));
		json.put("message", "短信发送失败,请重试");
		json.put("entity", null);

		return json;
	}

生成随机验证码:

/**获取k位由0-9的随机数字拼成的符串*/
	public static String getRandomNum(int k){
		String RandomNum = "";
		for (int i=0;i<k;i++){
			Random rd = new Random();
			RandomNum += (int)Math.floor(rd.nextInt(9));
		}
		return RandomNum;
	}

返回的json到ajax中,用

layer.msg(result.message, {icon: 1, shift: 6});

layer.msg(result.message, {icon: 5, shift: 6});
表示发送成功或失败
在这里插入图片描述
在这里插入图片描述

输入验证码后完成登录逻辑

用户登录条件
操作号码验证码
登录非空、格式、与第一次输入相同非空、正确

js中代码:

	/**
     * 根据手机号和验证码登陆
     */
    function sendPhoneCodelogin() {
        var mobileVal=$("#u-name-reg").val();//手机号
        var mobileCode=$("#pp-randomcode-reg").val();//验证码
        var firstMobile = $("#u-name-reg-first").val();//第一次输入的号码
        $.ajax({
            url:baselocation+'/user/ajax/phonelogin',
            type:'post',
            dataType:'json',
            data:{
                "mobileVal":mobileVal,
                "mobilecode":mobileCode,
                "firstMobile":firstMobile
            },
            success:function(result){
                if(result.success==true){
                    window.location.href="${ctx}";
                }else{
                    layer.msg(result.message, {icon: 5, shift: 6});
                }
            }
        })
    }

controller中代码:

	/**
	 * 手机号登录
	 */
	@RequestMapping("/phonelogin")
	@ResponseBody
	public Map<String,Object> phoneLogin(HttpServletRequest request, HttpServletResponse response){
		Map<String,Object> json = new HashMap<String,Object>();
		Map<String,Object> map = new HashMap<String, Object>();
		try{
			//获取手机号
			String mobile=request.getParameter("mobileVal");
            //第一次输入的号码
            String firstMobile = request.getParameter("firstMobile");
            //验证码
			String mobileCode=request.getParameter("mobilecode");
			//从缓存提取手机验证码
			String mobileCodeNum = (String) cache.get(mobile+"_mobileCodeNum");
			if(StringUtils.isEmpty(mobile)){
				json = this.setJson(false,"号码为空","mobile");
				return json;
			}
			if(!WebUtils.checkMobile(mobile)){
				json = this.setJson(false, "号码格式错误", null);
				return json;
			}
			if(StringUtils.isEmpty(firstMobile) || !mobile.equals(firstMobile)){
				json = this.setJson(false, "系统错误", null);
				return json;
			}
            if(StringUtils.isEmpty(mobileCode)){
                json = this.setJson(false, "验证码为空", null);
                return json;
            }
			if (mobileCode.equals(mobileCodeNum)){
				userService.phonelogin(mobile);
				cache.remove(mobile+"_mobileCodeNum");
			}else{
				json = this.setJson(false,"验证码错误","mobile");
				return json;
			}
			//进行登录操作
			map.put("ipForget","true");
			map.put("mobile",mobile);
			map.put("request",request);
			map.put("response",response);
			map=userService.queryDoUserLoginByMobile(map);
			json = this.setJson((boolean)map.get("success"), (String)map.get("message"), map);
			WebUtils.setCookie(response, UserCacheConstans.WEB_USER_LOGIN_PREFIX, (String) map.get("uuid"), 1);
		}catch (Exception e) {
			this.setAjaxException(json);
			logger.error("getVipInfo()---error",e);
		}
		return json;
	}

1.若条件不符合返回相应的信息回到ajax并用
layer.msg(result.message, {icon: 5, shift: 6});
弹框显示错误信息
2.若条件符合且验证码正确,将该用户数据封装在map对象中,调用queryDoUserLoginByMobile方法,执行登录操作

	/**
	 * 手机号登录操作
	 */
	public Map<String,Object> queryDoUserLoginByMobile(Map<String,Object> parameterMap) throws Exception {
		Map map = new HashMap();
		//--在线人数统计/限制 开始--
		if(!OnlineUtil.ckeckLimit(map)) {
			return map;
		}
		//--在线人数统计/限制 结束--
		HttpServletRequest request = (HttpServletRequest)parameterMap.get("request");
		HttpServletResponse response = (HttpServletResponse)parameterMap.get("response");
		String ipForget = (String)parameterMap.get("ipForget");
		String mobile = (String)parameterMap.get("mobile");
		User user = userMapper.queryUserByEmailOrMobile(mobile);//通过号码查询用户
		String account = user.getUserName();														
		String prefix = WebUtils.getCookie(request, UserCacheConstans.WEB_USER_LOGIN_PREFIX);
		if(StringUtils.isNotEmpty(prefix)){
			cache.remove(prefix);
		}
		if(user.getIsavalible()==2){
			map.put("success",false);
			map.put("message","该帐号已被禁用");
			return map;
		}
		cache.remove(UserCacheConstans.NAME_OR_PASS_ERR_COUNT+account);
		return queryDoLogin(user,ipForget,response,request);
	}

User user = userMapper.queryUserByEmailOrMobile(mobile);
由于号码是唯一的,所有根据号码查询获取该用户
user.getIsavalible()
若该账号被禁用,登录失败
return queryDoLogin(user,ipForget,response,request);
若该账号不被禁用,删除之前该用户的缓存,执行登录操作

	/**
	 * 登陆操作
	 */
	public Map queryDoLogin(User user, String ipForget, HttpServletResponse response, HttpServletRequest request)throws Exception{
		Map map = new HashMap();
		//用户密码不能让别人看到
		user.setPassword("");
		String uuid = RandomUtils.simpleUUID();
		//当前时间戳
		Long currentTimestamp=System.currentTimeMillis();
		user.setLoginTimeStamp(currentTimestamp);
		//当前时间
		user.setLoginDatatime(new Date());
		//客户端登录时间
		String userLoginDatatime = URLEncoder.encode(DateUtils.format(user.getLoginDatatime(),"yyyy-MM-dd HH:mm:ss"),"UTF-8").replaceAll("\\+",  "%20");
		if("true".equals(ipForget)){
			//缓存用户
			cache.set(uuid, user,UserCacheConstans.userTime);
			//缓存用户cookie key(后台获取后,可以清除登录用户的缓存)
			cache.set(UserCacheConstans.WEB_USER_LOGIN_PREFIX+user.getUserId(), uuid,UserCacheConstans.userTime);
			WebUtils.setCookie(response, UserCacheConstans.WEB_USER_LOGIN_PREFIX, uuid, (UserCacheConstans.userTime/60/60/24));
			WebUtils.setCookie(response, UserCacheConstans.WEB_USER_LOGINDATATIME, userLoginDatatime , (UserCacheConstans.userTime/60/60/24));
		}else{
			//缓存用户
			cache.set(uuid, user,86400);
			//缓存用户cookie key(后台获取后,可以清除登录用户的缓存)
			cache.set(UserCacheConstans.WEB_USER_LOGIN_PREFIX+user.getUserId(), uuid,UserCacheConstans.userTime);
			WebUtils.setCookie(response, UserCacheConstans.WEB_USER_LOGIN_PREFIX, uuid, 1);
			WebUtils.setCookie(response, UserCacheConstans.WEB_USER_LOGINDATATIME, userLoginDatatime , 1);
		}
		loginCommonOperate(request,user);
		// 登录时把cookie中的购物车信息加到数据库中
		shopcartService.addTempShopCart(request, response, Long.valueOf(user.getUserId()));
		map.put("success",true);
		map.put("message","登陆成功");
		map.put("user",user);
		map.put("uuid",uuid);

		//--在线人数统计/限制 开始--
		OnlineUtil.resetOnline(request, response, user.getUserId());
		//--在线人数统计/限制 结束--
		
		return map;
	}

将各种信息写入到缓存中,返回“登录成功”的信息

	if(result.success==true){
            window.location.href="${ctx}";
    }

登录成功后,跳转到网站首页

基于注册发送验证码

操作账号密码确认密码手机号
注册非空、格式 、未注册非空、格式非空、格式、与第一次输入相同非空、格式、未注册

jsp中:

<input id="u-name-reg" type="text" name="key" placeholder="请输入账号(英文、数字、减号或下划线且6-24个字符)" value=''  class="name-input" autocomplete="off"/>
<input id="u-password-reg" type="password" name="key" placeholder="请输入密码(包含字母、数字且不小于8位)" value='' class="bui-input"  autocomplete="off"/>
<input id="u-password-reg-again" type="password" name="key" placeholder="请确认密码" value='' style="margin:20px 0px" class="bui-input" autocomplete="off"/>
<input id="u-phone-reg" type="text" name="key" placeholder="请输入手机号码" value=''  class="name-input" autocomplete="off"/>
<input id="pp-randomcode-reg" class="name-input" placeholder="请输入验证码" name="" value="" onkeyup="$(this).next().next().next().html('');" maxlength="4" type="text">
<a class="vam ml10 disIb fl mobile-yz-btn" href="javascript:void(0)" onclick="sendPhoneCode()" title="">点击获取验证码</a>
<a class="loginBtn" type="button" onclick="Register()" title="注 册">注册</a>

1.可以同上面所说的“登录”一样将获取到的值通过ajax发送到controller中处理,再将结果返回
2.可以在js的function()中获取各个框中输入的值作判断处理,若不符合要求则无法跳到controller中处理,本例采用这种方式

 //发送验证码
    function sendPhoneCode() {
        var pageFrom = "register";
		var mobileVal=$("#u-phone-reg").val();
		
        var nameVal = $("#u-name-reg").val();
        if (nameVal == null || nameVal == "") {
            layer.msg("请输入账号", {icon: 5, shift: 6});
            return;
        }
        if (!isNaN(nameVal)) {
            layer.msg("账号不能全为数字", {icon: 5, shift: 6});
            return;
        }
        if (nameVal.length < 6 || nameVal.length > 24) {
            layer.msg("账号长度为6-24个字符", {icon: 5, shift: 6});
            return;
        }
        if (usernameRegex.test(nameVal) == false) {//账号格式
            layer.msg("账号仅支持英文、数字、减号或下划线", {icon: 5, shift: 6});
            return;
        }
        var password = $("#u-password-reg").val();
        if (password == null || password == "") {
            layer.msg("请输入密码", {icon: 5, shift: 6});
            return;
        }
        password = encrypt(password);
        var passwordAgain = $("#u-password-reg-again").val();
        if (passwordAgain == null || passwordAgain == "") {
            layer.msg("请确认密码", {icon: 5, shift: 6});
            return;
        }
        passwordAgain = encrypt(passwordAgain);
        if (password!=passwordAgain) {
            layer.msg("两次密码不一致", {icon: 5, shift: 6});
            return;
        }
        $.ajax({
            url:baselocation+'/login/ajax/sendPhoneMsg',
            type:'post',
            dataType:'json',
            data:{
                "nameVal":nameVal,
                "mobileVal":mobileVal,
                "pageFrom":pageFrom
            },
            success:function(result){
                if(result.success==true){
                    layer.msg("短信发送成功", {icon: 1, shift: 6});
                    var timeTicket;
                    var timeNum = 60;
                    //$("#phoneClick").css("visibility","hidden");
                    // $("#recoverPhoneClick").css("visibility","visible");
                    clearInterval(timeTicket);
                    /*当点击获取验证码后设置60秒计时不可点击*/
                    timeTicket = setInterval(function () {
                        if (timeNum>1){
                            timeNum--;
                            /*设置按钮不可点击*/
                            $(".mobile-yz-btn").addClass("mobile-yz-btn-no");
                            $(".mobile-yz-btn").attr("onclick","");
                            $(".mobile-yz-btn").text(timeNum+"秒后重新获取");
                        }else if (timeNum==1){
                            $(".mobile-yz-btn").text("点击获取验证码");
                            $(".mobile-yz-btn").attr("onclick","sendPhoneRegister()");
                            $(".mobile-yz-btn").removeClass("mobile-yz-btn-no");
                            timeNum = 60;

                            clearInterval(timeTicket);

                            //刷新验证码
                            $(".js-verify-refresh.c-green").click();
                        }
                    },1000);
                }else{
                    layer.msg(result.message, {icon: 5, shift: 6});
                }
            }
        })
    }

其余代码跟登录相似,只是pageFrom的值不同,这样controller中才会根据不同页面对“用户名”和“手机号”作判断。若该账号或手机号已注册,则无法发送验证码,相比在点击“注册”时对之作判断,可以减少很多“无用”信息

		if(pageFrom.equals("register")){
              String userName = request.getParameter("nameVal");
              if(userService.checkUsername(userName)){
                  json = this.setJson(false,"该用户名已注册", null);
                  return json;
              }
              if(userService.checkMobile(mobile)){
                  json = this.setJson(false,"该号码已注册", null);
                  return json;
              }
          }

输入验证码后完成注册逻辑

用户注册条件
操作号码验证码
注册非空、格式、未注册、与发送验证码的号码相同非空、正确

其余逻辑均与“登录”时相似,注册成功后,登录该用户,显示主页面

Tips:本人第一篇博客,若有不足之处,欢迎大家予以斧正。

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值