手機驗證碼是我們日常生活使用軟件都會用到的功能
那麼 假設讓我們去做出這個功能 該如何實現呢
實現的方法有很多 有的做緩存 有的存庫裏
這邊我簡單記錄後者的實現過程!
首先 做一個按鈕 將該用戶的手機號 進行提交 按鈕和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
這個方法的調用 就是在 驗證提交過來的接口地方進行調用
到了這邊 手機短信驗證碼的功能就實現了!
因爲不是純原生的 有用到一些助手函數的寫法
有問題歡迎在評論區留言
覺得有用的就點個贊 加個關注吧!