手機短信驗證碼業務邏輯實現

手機驗證碼是我們日常生活使用軟件都會用到的功能 

那麼 假設讓我們去做出這個功能 該如何實現呢

實現的方法有很多  有的做緩存 有的存庫裏

這邊我簡單記錄後者的實現過程!


首先 做一個按鈕  將該用戶的手機號 進行提交 按鈕和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

這個方法的調用 就是在 驗證提交過來的接口地方進行調用


到了這邊 手機短信驗證碼的功能就實現了!

因爲不是純原生的 有用到一些助手函數的寫法

有問題歡迎在評論區留言

覺得有用的就點個贊 加個關注吧!

 

 

 

 

 

 

 

 

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