手机短信验证码业务逻辑实现

手机验证码是我们日常生活使用软件都会用到的功能 

那么 假设让我们去做出这个功能 该如何实现呢

实现的方法有很多  有的做缓存 有的存库里

这边我简单记录后者的实现过程!


首先 做一个按钮  将该用户的手机号 进行提交 按钮和ajax的提交代码如下

<div class="inputbox phone">
    <input type="text" id="phone" value="[[$user.phone]]" disabled>
</div>
<div class="inputbox Vecode">
	<input type="text" id="smscode" placeholder="短信验证码">
	<a href="javascript:;" class="getVecodeBtn"><p>获取验证码</p></a>
</div>


$('.getVecodeBtn').on('click',function(){
        var obj=$(this);
		var phone='';
        if(obj.attr('is-timer')){
            return true;
        }
        ajax({
            url:global.appurl+'a=getPhoneCode',
            data:{phone:phone,stype:4},
            success:function(json){
                if(json.code!=1){
                    _alert(json.msg);
                    return;
                }
                smsTimer(obj);
            }
        });
    });

getPhoneCode 这个就是 我们后端的获取验证码的方法

public function _getPhoneCode(){
//获取当前用户提交过来的手机号
        $phone = $this->params['phone'];
        //如果没有提交手机号
        if(!$phone){
//判断用户是否已经登陆
            $user=isLogin();
//没有登陆就不能继续
            if(!$user){
                jReturn('-1','请输入正确的手机号码');
            }
//有登陆 就获取当前用户的手机号
            $phone=$user['phone'];
        }
        $stype = intval(getParam('stype'));
        if(!isPhone($phone)){
            jReturn('-1','手机号码不正确');
        }
        if(!$stype){
            jReturn('-1','验证码类型不正确');
        }
        $data=array(
            'phone'=>$phone,
            'stype'=>$stype
        );
        $res=getPhoneCode($data);
        exit(json_encode($res));
    }

getPhoneCode这个方法 就是主要处理验证码的地方  代码如下:

//这个参数当作一个标识
if(!$data['stype']||!$data['phone']){
		return array('code'=>'-1','msg'=>'缺少验证参数');//缺少验证参数
	}
$mysql=new Mysql(0);
$limit_time=60;//60秒以内不能重复获取
$list=$mysql->fetchRows("select * from sys_vcode where phone='{$data['phone']}' and stype='{$data['stype']}' and UNIX_TIMESTAMP()-create_time<{$limit_time}",1,5);
$cnt=count($list);
if($cnt>0){
    //获取验证码过于频繁,请稍后再试
	return array('code'=>'-1','msg'=>'获取验证码过于频繁,请稍后再试');
}
//这个地方是短信服务商的相关配置 
$sys_sms=getConfig('sys_sms',$mysql);
//产生一个随机验证码
$code = rand(123456,999999);
//短信内容	
$content=str_replace('{$code}',$code,$sys_sms['tpl']);
//发送到第三方
$result=sendSms($data['phone'],$content);
if($result!='1'){
	return array('code'=>'-1','msg'=>'短信发送失败'.$result,$content);//短信发送失败
}
//记录此次的验证码
$db_data=array(
	'code'=>$code,
	'phone'=>$data['phone'],
	'stype'=>$data['stype'],
	'create_time'=>NOW_TIME,
	'create_ip'=>CLIENT_IP,
	'scon'=>$content
);
$res=$mysql->insert($db_data,'sys_vcode');
if(!$res){
	return array('code'=>'-1','msg'=>'系统繁忙请稍后再试');//系统繁忙请稍后再试
}
return array('code'=>'1','msg'=>'发送成功');//发送成功

整理下 这个验证码的产生和记录逻辑 :就是 生成一个验证码 存到数据库中 并记录这个验证码的产生时间

时间间隔60秒  在时间内 就不能在生成验证码 

如果不在时间间隔内  随机数生成验证码 之后 将验证码 拼接到短信的内容 还有手机号 

一起推送给第三方服务商 

并将这次的验证码 手机号 创建时间 都记录到表中


记录验证码的表的sql语句:

CREATE TABLE `sys_vcode` (
	`id` INT(11) NOT NULL AUTO_INCREMENT,
	`stype` TINYINT(4) NULL DEFAULT NULL COMMENT '验证码分类',
	`phone` VARCHAR(16) NULL DEFAULT NULL COMMENT '手机号',
	`code` VARCHAR(8) NULL DEFAULT NULL COMMENT '验证码',
	`status` TINYINT(2) NULL DEFAULT '0' COMMENT '状态',
	`verify_num` TINYINT(4) NULL DEFAULT '0' COMMENT '验证次数',
	`create_time` INT(11) NULL DEFAULT NULL COMMENT '创建时间',
	`verify_time` INT(11) NULL DEFAULT '0' COMMENT '对比时间',
	`create_ip` VARCHAR(16) NULL DEFAULT NULL COMMENT '生成ip',
	`scon` VARCHAR(256) NULL DEFAULT NULL COMMENT '短信内容',
	PRIMARY KEY (`id`) USING BTREE,
	INDEX `sp` (`stype`, `phone`) USING BTREE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
ROW_FORMAT=COMPACT
AUTO_INCREMENT=5631
;

最后一步 如何根据提交过来的验证码 判断是否正确

//验证参数
if(!$data['stype']||!$data['code']||!$data['phone']){
	return array('code'=>'-1','msg'=>'缺少验证参数');//缺少验证参数
}
$mysql=new Mysql(0);
//查询上述创建的表中 有没有存在这个二维码和手机对应的数据
$item=$mysql->fetchRow("select * from sys_vcode where phone='{$data['phone']}' and stype='{$data['stype']}' order by id desc");
//如果不存在
if(!$item['id']){
	return array('code'=>'-1','msg'=>'该短信验证码不正确');//该短信验证码不正确
}
//如果这个验证码验证的次数大于两次
if($item['status']||$item['verify_num']>2){
	return array('code'=>'-1','msg'=>'请重新获取短信验证码');//请重新获取短信验证码
}
//查到验证码且验证使用未达到限制次数
$msg='';
$db_data=array('verify_num'=>$item['verify_num']+1);
if($data['code']==$item['code']){
//检测验证码有效期
if(NOW_TIME-$item['create_time']>1800){
	$msg='该短信验证码已失效';//该短信验证码已失效
	$db_data['status']=1;
    }else{
	    $db_data['status']=2;
    }
}else{
	$msg='该短信验证码不正确';//该短信验证码不正确
	if($db_data['verify_num']>2){
			$db_data['status']=1;
		}
	}
$db_data['verify_time']=NOW_TIME;
$res=$mysql->update($db_data,"id={$item['id']}",'sys_vcode');
if(!$res){
	$msg='该短信验证码不正确';//该短信验证码不正确
}
if($msg){
	return array('code'=>'-1','msg'=>$msg);
}
return array('code'=>'1','msg'=>'验证通过');//验证通过

验证的逻辑就是:根据提交过来的验证码 先判断库里存不存在 

如果存在 判断这个验证码的校验次数有几次 大于两次 就要重新获取

如果都没有问题 那就判断验证码是否在有效范围内

给验证码次数加1  并更新对应的码信息

都没有问题 就返回true

这个方法的调用 就是在 验证提交过来的接口地方进行调用


到了这边 手机短信验证码的功能就实现了!

因为不是纯原生的 有用到一些助手函数的写法

有问题欢迎在评论区留言

觉得有用的就点个赞 加个关注吧!

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章