摘要:前言注冊(cè)時(shí)經(jīng)常需要用到短信驗(yàn)證碼,本文記錄一下思路和具體實(shí)現(xiàn)。短信驗(yàn)證平臺(tái)使用云片,短信驗(yàn)證碼的生成使用。云片發(fā)送短信驗(yàn)證碼到指定手機(jī)號(hào)。用戶輸入短信驗(yàn)證碼。
前言
注冊(cè)時(shí)經(jīng)常需要用到短信驗(yàn)證碼,本文記錄一下思路和具體實(shí)現(xiàn)。
短信驗(yàn)證平臺(tái)使用云片,短信驗(yàn)證碼的生成使用thinkphp。
1、用戶輸入手機(jī)號(hào),請(qǐng)求獲取短信驗(yàn)證碼。
2、thinkphp生成短信驗(yàn)證碼,存儲(chǔ),同時(shí)和其他參數(shù)一起發(fā)送請(qǐng)求給云片。
3、云片發(fā)送短信驗(yàn)證碼到指定手機(jī)號(hào)。
4、用戶輸入短信驗(yàn)證碼。
5、thinkphp根據(jù)驗(yàn)證碼是否正確、驗(yàn)證碼是否過期兩個(gè)條件判斷是否驗(yàn)證通過。
接口地址:https://sms.yunpian.com/v1/sms/send.json。
使用postman,輸入三個(gè)必須的參數(shù)apikey、mobile和text。
使用php的curl函數(shù)發(fā)起https請(qǐng)求,帶入?yún)?shù)apikey、mobile和text。
// 獲取短信驗(yàn)證碼 public function getSMSCode(){ // create curl resource $ch = curl_init(); // set url $url = "https://sms.yunpian.com/v1/sms/send.json"; curl_setopt($ch, CURLOPT_URL, $url); // set param $paramArr = array( "apikey" => "******", "mobile" => "******", "text" => "【小太陽(yáng)】您的驗(yàn)證碼是1234" ); $param = ""; foreach ($paramArr as $key => $value) { $param .= urlencode($key)."=".urlencode($value)."&"; } $param = substr($param, 0, strlen($param)-1); curl_setopt($ch, CURLOPT_POSTFIELDS, $param); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_POST, 1); //curl默認(rèn)不支持https協(xié)議,設(shè)置不驗(yàn)證協(xié)議 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //return the transfer as a string curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // $output contains the output string $output = curl_exec($ch); // close curl resource to free up system resources curl_close($ch); echo $output; }生成隨機(jī)短信驗(yàn)證碼
默認(rèn)生成四位的隨機(jī)短信驗(yàn)證碼。
// 生成短信驗(yàn)證碼 public function createSMSCode($length = 4){ $min = pow(10 , ($length - 1)); $max = pow(10, $length) - 1; return rand($min, $max); }整合
在數(shù)據(jù)庫(kù)新建表sun_smscode:
DROP TABLE IF EXISTS `sun_smscode`; CREATE TABLE `sun_smscode` ( `id` int(8) NOT NULL AUTO_INCREMENT, `mobile` varchar(11) NOT NULL, `code` int(4) NOT NULL, `create_at` datetime NOT NULL, `update_at` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
thinkphp代碼:
// 獲取短信驗(yàn)證碼 public function getSMSCode(){ // create curl resource $ch = curl_init(); // set url $url = "https://sms.yunpian.com/v1/sms/send.json"; curl_setopt($ch, CURLOPT_URL, $url); // set param $mobile = $_POST["mobile"]; $code = $this->createSMSCode(); $paramArr = array( "apikey" => "******", "mobile" => $mobile, "text" => "【小太陽(yáng)】您的驗(yàn)證碼是".$code ); $param = ""; foreach ($paramArr as $key => $value) { $param .= urlencode($key)."=".urlencode($value)."&"; } $param = substr($param, 0, strlen($param)-1); curl_setopt($ch, CURLOPT_POSTFIELDS, $param); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //不驗(yàn)證證書下同 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //return the transfer as a string curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // $output contains the output string $output = curl_exec($ch); // close curl resource to free up system resources curl_close($ch); //$outputJson = json_decode($output); $outputArr = json_decode($output, true); //echo $outputJson->code; //echo $outputArr["code"]; if($outputArr["code"] == "0"){ $data["mobile"] = $mobile; $data["code"] = $code; $smscode = D("smscode"); $smscodeObj = $smscode->where("mobile="$mobile"")->find(); if($smscodeObj){ $data["update_at"] = date("Y-m-d H:i:s"); $success = $smscode->where("mobile="$mobile"")->save($data); if($success !== false){ $result = array( "code" => "0", "ext" => "修改成功", "obj" => $smscodeObj ); } echo json_encode($result,JSON_UNESCAPED_UNICODE); }else{ $data["create_at"] = date("Y-m-d H:i:s"); $data["update_at"] = $data["create_at"]; if($smscode->create($data)){ $id = $smscode->add(); if($id){ $smscode_temp = $smscode->where("id="$id"")->find(); $result = array( "code"=> "0", "ext"=> "創(chuàng)建成功", "obj"=>$smscode_temp ); echo json_encode($result,JSON_UNESCAPED_UNICODE); } } } } }驗(yàn)證短信驗(yàn)證碼
驗(yàn)證短信驗(yàn)證碼時(shí)間是否過期,驗(yàn)證短信驗(yàn)證碼是否正確。
// 驗(yàn)證短信驗(yàn)證碼是否有效 public function checkSMSCode(){ $mobile = $_POST["mobile"]; $code = $_POST["code"]; $nowTimeStr = date("Y-m-d H:i:s"); $smscode = D("smscode"); $smscodeObj = $smscode->where("mobile="$mobile"")->find(); if($smscodeObj){ $smsCodeTimeStr = $smscodeObj["update_at"]; $recordCode = $smscodeObj["code"]; $flag = $this->checkTime($nowTimeStr, $smsCodeTimeStr); if(!$flag){ $result = array( "code" => "1", "ext" => "驗(yàn)證碼過期,請(qǐng)刷新后重新獲取" ); echo json_encode($result,JSON_UNESCAPED_UNICODE); return; } if($code != $recordCode){ $result = array( "code" => "2", "ext" => "驗(yàn)證碼錯(cuò)誤,請(qǐng)重新輸入" ); echo json_encode($result,JSON_UNESCAPED_UNICODE); return; } $result = array( "code" => "0", "ext" => "驗(yàn)證通過" ); echo json_encode($result,JSON_UNESCAPED_UNICODE); } } // 驗(yàn)證驗(yàn)證碼時(shí)間是否過期 public function checkTime($nowTimeStr,$smsCodeTimeStr){ //$nowTimeStr = "2016-10-15 14:39:59"; //$smsCodeTimeStr = "2016-10-15 14:30:00"; $nowTime = strtotime($nowTimeStr); $smsCodeTime = strtotime($smsCodeTimeStr); $period = floor(($nowTime-$smsCodeTime)/60); //60s if($period>=0 && $period<=20){ return true; }else{ return false; } }改進(jìn)
為了防止短信轟炸,在請(qǐng)求獲取短信驗(yàn)證碼時(shí),需要加入圖片驗(yàn)證碼。
thinkphp提供了生成圖片驗(yàn)證碼的函數(shù),下面我們來實(shí)現(xiàn)驗(yàn)證碼的生成、刷新和驗(yàn)證。
生成和刷新圖片驗(yàn)證碼// 獲取圖片驗(yàn)證碼,刷新圖片驗(yàn)證碼 public function getPicCode(){ $config = array( "fontSize"=>30, // 驗(yàn)證碼字體大小 "length"=>4, // 驗(yàn)證碼位數(shù) "useNoise"=>false, // 關(guān)閉驗(yàn)證碼雜點(diǎn) "expire"=>600 ); $Verify = new ThinkVerify($config); $Verify->entry(2333);//2333是驗(yàn)證碼標(biāo)志 }
假設(shè),該函數(shù)的對(duì)應(yīng)url為http://localhost/owner-bd/index.php/Home/CheckCode/getPicCode,那么,圖片驗(yàn)證碼的地址就是這個(gè)url,放入頁(yè)面圖片標(biāo)簽的src屬性即可。
驗(yàn)證圖片驗(yàn)證碼// 驗(yàn)證驗(yàn)證碼是否正確 public function checkPicCode($code){ $verify = new ThinkVerify(); if($verify->check($code, 2333)){ $result = array( "code" => "0", "ext" => "驗(yàn)證通過" ); echo json_encode($result,JSON_UNESCAPED_UNICODE); }else{ $result = array( "code" => "1", "ext" => "驗(yàn)證碼錯(cuò)誤,請(qǐng)重新輸入" ); echo json_encode($result,JSON_UNESCAPED_UNICODE); }; }
以上方法,我們利用了thinkphp提供的check方法,實(shí)現(xiàn)起來很簡(jiǎn)單。但是,如果想要得到驗(yàn)證細(xì)節(jié),就沒有辦法了。比如,驗(yàn)證碼錯(cuò)誤,可能驗(yàn)證碼超時(shí),可能因?yàn)檩斎腧?yàn)證碼錯(cuò)誤,可能因?yàn)轵?yàn)證碼已經(jīng)使用過等等。必要的時(shí)候,可以重寫thinkphp的驗(yàn)證碼類,或者重寫thinkphp的check方法。
跑通前后端 后端修改驗(yàn)證圖片驗(yàn)證碼函數(shù),改為被調(diào)用函數(shù):
public function checkPicCode($picCode){ $verify = new ThinkVerify(); if($verify->check($picCode, 2333)){ return true; }else{ return false; }; }
在獲取短信驗(yàn)證碼函數(shù)的最頂部,添加調(diào)用圖片驗(yàn)證碼函數(shù),只有通過驗(yàn)證,才發(fā)送請(qǐng)求給云片。
// 獲取短信驗(yàn)證碼 public function getSMSCode(){ $picCode = $_POST["picCode"]; if(!$this->checkPicCode($picCode)){ $result = array( "code" => "1", "ext" => "驗(yàn)證碼錯(cuò)誤,請(qǐng)重新輸入" ); echo json_encode($result,JSON_UNESCAPED_UNICODE); return; } /*省略*/ }前端核心代碼
注冊(cè)
// register.js angular.module("sunApp").controller("registerController", function ($scope,$http,$httpParamSerializer,$state,$interval) { $scope.picCodeUrl = "/owner-bd/index.php/Home/CheckCode/getPicCode"; $scope.isShow1 = true; $scope.isShow2 = false; $scope.btnSMSText = "獲取驗(yàn)證碼"; $scope.btnSMSDisabled = false; $scope.checkOver = false; // 獲取短信驗(yàn)證碼 $scope.getSMSCode = function(){ var param = { mobile: $scope.mobile, picCode: $scope.picCode }; $http({ method:"POST", url:"/owner-bd/index.php/Home/SMS/getSMSCode", //url: "/owner-fd/mock/common.json", headers:{ "Content-Type":"application/x-www-form-urlencoded" }, dataType: "json", data: $httpParamSerializer(param) }).then(function successCallback(response) { console.log(response.data); if(response.data.code == "0"){ $scope.checkOver = true; $scope.btnSMSDisabled = true; var time = 60; var timer = null; timer = $interval(function(){ time = time - 1; $scope.btnSMSText = time+"秒"; if(time == 0) { $interval.cancel(timer); $scope.btnSMSDisabled = false; $scope.btnSMSText = "重新獲取"; } }, 1000); } }, function errorCallback(response) { console.log(response.data); }); } // 驗(yàn)證短信驗(yàn)證碼 $scope.next = function(){ if(!$scope.checkOver){ console.log("未通過驗(yàn)證"); return; } var param = { mobile: $scope.mobile, code: $scope.SMSCode }; $http({ method:"POST", url:"/owner-bd/index.php/Home/SMS/checkSMSCode", //url: "/owner-fd/mock/common.json", headers:{ "Content-Type":"application/x-www-form-urlencoded" }, dataType: "json", data: $httpParamSerializer(param) }).then(function successCallback(response) { console.log(response.data); if(response.data.code == "0"){ $scope.isShow1 = false; $scope.isShow2 = true; } }, function errorCallback(response) { console.log(response.data); }); } // 刷新圖片驗(yàn)證碼 $scope.refresh = function(){ $scope.picCodeUrl = "/owner-bd/index.php/Home/CheckCode/getPicCode?"+Math.random(); } });優(yōu)化
以上代碼,安全性不是很好,我們可以利用工具繞過前端驗(yàn)證。為了避免這個(gè)問題,可以在checkPicCode和checkSMSCode函數(shù)中添加session值來標(biāo)記。
$_SESSION["checkPicCode"] = true; $_SESSION["checkSMSCode"] = true;
在最后一步,向數(shù)據(jù)庫(kù)中添加用戶時(shí),先驗(yàn)證一下兩個(gè)session值是否都為true,都為true時(shí)再添加。
成果 后記以后也許有用的代碼:
echo json_encode($_SESSION);// 打印出session中的數(shù)據(jù) echo session_id();// 打印當(dāng)前session的id書簽
云片網(wǎng)
https://www.yunpian.com/
cURL函數(shù)
http://php.net/manual/zh/ref....
curl 基礎(chǔ)例子
http://php.net/manual/zh/curl...
在PHP語(yǔ)言中使用JSON
http://www.ruanyifeng.com/blo...
thinkphp驗(yàn)證碼
http://document.thinkphp.cn/m...
修改ThinkPHP的驗(yàn)證碼類
http://www.cnblogs.com/BTMast...
ThinkPHP 3.2版本 , 無法讀取$_SESSION["verify_code"]
http://www.cnblogs.com/lovezb...
LICEcap - Download
http://licecap.en.softonic.com/
gif動(dòng)態(tài)圖局部加馬賽克模糊廣告文字
http://www.leawo.cn/space-138...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/21933.html
摘要:本方法基于,用到了,當(dāng)然具體項(xiàng)目中也可以不用,下面我就按步驟來寫下來。 本方法基于Thinkphp,用到了jquery.validate,當(dāng)然具體項(xiàng)目中也可以不用,下面我就按步驟來寫下來。 1.準(zhǔn)備 1.登陸http://www.alidayu.com,進(jìn)入網(wǎng)址用淘寶號(hào)登陸即可2.進(jìn)入管理中心 showImg(https://segmentfault.com/img/bVQTOk?w=...
摘要:之前使用的阿里大于,不過很坑的是,新接入的都不能用了,融入進(jìn)了阿里云服務(wù),當(dāng)然阿里大于的老用戶還可以繼續(xù)用阿里大于首先還是接入,上圖找到短信服務(wù)設(shè)置短信簽名和短信模板設(shè)置或找到或下載文檔打開下載下來的文檔,只需要,將其改名為,并放到項(xiàng)目根目 之前使用的阿里大于,不過很坑的是,新接入的都不能用了,融入進(jìn)了阿里云服務(wù),當(dāng)然阿里大于的老用戶還可以繼續(xù)用阿里大于 首先還是接入,上圖: (1)找...
摘要:經(jīng)過各大短信平臺(tái)進(jìn)行比較后,選擇了阿里大于,一個(gè)阿里巴巴的云通信平臺(tái),下面我將這次開發(fā)經(jīng)驗(yàn)和遇到的一些問題分享出來。 最近在做一個(gè)商城的項(xiàng)目,其中注冊(cè)、找回密碼、換綁手機(jī)等功能都需要用到驗(yàn)證碼,考慮到上線的安全問題,我決定用手機(jī)驗(yàn)證碼來提高安全性。經(jīng)過各大短信平臺(tái)進(jìn)行比較后,選擇了阿里大于,一個(gè)阿里巴巴的云通信平臺(tái),下面我將這次開發(fā)經(jīng)驗(yàn)和遇到的一些問題分享出來。 1.登錄平臺(tái) 阿里大...
摘要:經(jīng)過各大短信平臺(tái)進(jìn)行比較后,選擇了阿里大于,一個(gè)阿里巴巴的云通信平臺(tái),下面我將這次開發(fā)經(jīng)驗(yàn)和遇到的一些問題分享出來。 最近在做一個(gè)商城的項(xiàng)目,其中注冊(cè)、找回密碼、換綁手機(jī)等功能都需要用到驗(yàn)證碼,考慮到上線的安全問題,我決定用手機(jī)驗(yàn)證碼來提高安全性。經(jīng)過各大短信平臺(tái)進(jìn)行比較后,選擇了阿里大于,一個(gè)阿里巴巴的云通信平臺(tái),下面我將這次開發(fā)經(jīng)驗(yàn)和遇到的一些問題分享出來。 1.登錄平臺(tái) 阿里大...
閱讀 726·2023-04-25 17:54
閱讀 2986·2021-11-18 10:02
閱讀 1143·2021-09-28 09:35
閱讀 663·2021-09-22 15:18
閱讀 2867·2021-09-03 10:49
閱讀 3065·2021-08-10 09:42
閱讀 2588·2019-08-29 16:24
閱讀 1267·2019-08-29 15:08