Heim > Artikel > Backend-Entwicklung > Thinkphp implementiert die SMS-Verifizierungsregistrierungsfunktion_php-Beispiel
Vorwort
Bei der Registrierung werden häufig SMS-Verifizierungscodes verwendet. In diesem Artikel werden die Ideen und die konkrete Umsetzung aufgezeichnet.
Die SMS-Verifizierungsplattform verwendet Yunpian und der SMS-Verifizierungscode wird mit thinkphp generiert.
Gedanken
1. Der Benutzer gibt die Mobiltelefonnummer ein und fordert den Erhalt des SMS-Bestätigungscodes an.
2. Thinkphp generiert einen SMS-Bestätigungscode, speichert ihn und sendet die Anfrage zusammen mit anderen Parametern an Yunpian.
3. Yunpian sendet einen Bestätigungscode per SMS an die angegebene Mobiltelefonnummer.
4. Der Benutzer gibt den SMS-Bestätigungscode ein.
5. thinkphp bestimmt anhand von zwei Bedingungen, ob die Verifizierung erfolgreich ist: ob der Verifizierungscode korrekt ist und ob der Verifizierungscode abgelaufen ist.
Code-Implementierung
Verifizierungsschnittstelle
Schnittstellenadresse: https://sms.yunpian.com/v1/sms/send.json.
Verwenden Sie Postman und geben Sie die drei notwendigen Parameter apikey, mobile und text ein.
PHP initiiert http/https-Anfrage
Verwenden Sie die Curl-Funktion von PHP, um eine https-Anfrage zu initiieren und dabei die Parameter apikey, mobile und text einzugeben.
// 获取短信验证码 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' => '【小太阳】您的验证码是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默认不支持https协议,设置不验证协议 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; }
Zufälligen SMS-Bestätigungscode generieren
Standardmäßig wird ein vierstelliger zufälliger SMS-Bestätigungscode generiert.
// 生成短信验证码 public function createSMSCode($length = 4){ $min = pow(10 , ($length - 1)); $max = pow(10, $length) - 1; return rand($min, $max); }
Integration
Erstellen Sie eine neue Tabelle sun_smscode in der Datenbank:
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代码: // 获取短信验证码 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' => '【小太阳】您的验证码是'.$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); //不验证证书下同 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'=> '创建成功', 'obj'=>$smscode_temp ); echo json_encode($result,JSON_UNESCAPED_UNICODE); } } } } }
Bestätigungs-SMS-Bestätigungscode
Überprüfen Sie, ob die Zeit für den SMS-Bestätigungscode abgelaufen ist und ob der SMS-Bestätigungscode korrekt ist.
// 验证短信验证码是否有效 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' => '验证码过期,请刷新后重新获取' ); echo json_encode($result,JSON_UNESCAPED_UNICODE); return; } if($code != $recordCode){ $result = array( 'code' => '2', 'ext' => '验证码错误,请重新输入' ); echo json_encode($result,JSON_UNESCAPED_UNICODE); return; } $result = array( 'code' => '0', 'ext' => '验证通过' ); echo json_encode($result,JSON_UNESCAPED_UNICODE); } } // 验证验证码时间是否过期 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; } }
Verbesserungen
Um SMS-Bombardierungen zu verhindern, müssen Sie bei der Anforderung eines SMS-Bestätigungscodes einen Bildbestätigungscode angeben.
thinkphp bietet eine Funktion zum Generieren von Bildbestätigungscodes. Implementieren wir die Generierung, Aktualisierung und Überprüfung von Bestätigungscodes.
Bildbestätigungscodes generieren und aktualisieren
// 获取图片验证码,刷新图片验证码 public function getPicCode(){ $config = array( 'fontSize'=>30, // 验证码字体大小 'length'=>4, // 验证码位数 'useNoise'=>false, // 关闭验证码杂点 'expire'=>600 ); $Verify = new \Think\Verify($config); $Verify->entry(2333);//2333是验证码标志 }
Angenommen, die entsprechende URL dieser Funktion ist http://localhost/owner-bd/index.php/Home/CheckCode/getPicCode. Dann ist die Adresse des Bildverifizierungscodes diese URL und wird in der Quelle platziert Attribut des Seitenbild-Tags. Das ist es.
Bestätigungsbild-Bestätigungscode
// 验证验证码是否正确 public function checkPicCode($code){ $verify = new \Think\Verify(); if($verify->check($code, 2333)){ $result = array( 'code' => '0', 'ext' => '验证通过' ); echo json_encode($result,JSON_UNESCAPED_UNICODE); }else{ $result = array( 'code' => '1', 'ext' => '验证码错误,请重新输入' ); echo json_encode($result,JSON_UNESCAPED_UNICODE); }; }
Für die obige Methode verwenden wir die von thinkphp bereitgestellte Prüfmethode, die sehr einfach zu implementieren ist. Wenn Sie jedoch Verifizierungsdetails erhalten möchten, gibt es keine Möglichkeit. Wenn beispielsweise der Bestätigungscode falsch ist, ist möglicherweise eine Zeitüberschreitung des Bestätigungscodes aufgetreten, der Bestätigungscode wurde möglicherweise falsch eingegeben, der Bestätigungscode wurde möglicherweise verwendet usw. Bei Bedarf können Sie die Verifizierungscodeklasse von thinkphp oder die Prüfmethode von thinkphp neu schreiben.
Front- und Backends durchlaufen
Backend-Änderung
Überprüfen Sie die Funktion des Bildbestätigungscodes und ändern Sie sie in die aufgerufene Funktion:
public function checkPicCode($picCode){ $verify = new \Think\Verify(); if($verify->check($picCode, 2333)){ return true; }else{ return false; }; }
Fügen Sie oben in der Funktion zum Abrufen des SMS-Bestätigungscodes die Funktion zum Aufrufen des Bildbestätigungscodes hinzu. Erst wenn die Bestätigung bestanden wurde, wird die Anfrage an Yunpian gesendet.
// 获取短信验证码 public function getSMSCode(){ $picCode = $_POST['picCode']; if(!$this->checkPicCode($picCode)){ $result = array( 'code' => '1', 'ext' => '验证码错误,请重新输入' ); echo json_encode($result,JSON_UNESCAPED_UNICODE); return; } /*省略*/ }
Front-End-Kerncode
<!--register.html--> <!DOCTYPE html> <html lang="zh" ng-app="sunApp"> <head> <meta charset="UTF-8"> <title>注册</title> </head> <body ng-controller="registerController"> <form action="" class="register-form" ng-show="isShow1"> <div class="input-group"> <input type="text" class="mobile" ng-model="mobile" placeholder="手机号"> </div> <div class="input-group"> <input type="text" class="pic-code" ng-model="picCode" placeholder="图片验证码"> <img class="img" src="{{picCodeUrl}}" alt="" ng-click="refresh()"> </div> <div class="input-group"> <input type="text" class="sms-code" ng-model="SMSCode" placeholder="短信验证码"> <button class="btn-sms" ng-click="getSMSCode()" ng-disabled="btnSMSDisabled">{{btnSMSText}}</button> </div> <button class="confirm-btn" ng-click="next()">下一步</button> </form> <form action="" class="register-form" ng-show="isShow2"> <div class="input-group"> <input type="text" class="mobile" ng-model="mobile" placeholder="手机号" disabled="true"> </div> <div class="input-group"> <input type="password" class="password" ng-model="password" placeholder="请输入密码"> <input type="password" class="password" ng-model="password2" placeholder="请再次输入密码"> </div> <button class="confirm-btn" ng-click="getSMSCode()">注册</button> </form> </body> </html> // 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 = '获取验证码'; $scope.btnSMSDisabled = false; $scope.checkOver = false; // 获取短信验证码 $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); }); } // 验证短信验证码 $scope.next = function(){ if(!$scope.checkOver){ console.log('未通过验证'); 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); }); } // 刷新图片验证码 $scope.refresh = function(){ $scope.picCodeUrl = '/owner-bd/index.php/Home/CheckCode/getPicCode?'+Math.random(); } });
Optimierung
Die Sicherheit des oben genannten Codes ist nicht sehr gut. Wir können Tools verwenden, um die Front-End-Überprüfung zu umgehen. Um dieses Problem zu vermeiden, können Sie den zu markierenden Sitzungswert in den Funktionen checkPicCode und checkSMSCode hinzufügen.
$_SESSION['checkPicCode'] = true; $_SESSION['checkSMSCode'] = true;
Im letzten Schritt überprüfen Sie beim Hinzufügen eines Benutzers zur Datenbank zunächst, ob beide Sitzungswerte wahr sind, und fügen Sie sie dann hinzu, wenn beide wahr sind.
Ergebnisse
Postskriptum
Code, der in Zukunft nützlich sein könnte:
echo json_encode($_SESSION);// 打印出session中的数据 echo session_id();// 打印当前session的id
Das Obige ist die vom Herausgeber eingeführte Thinkphp-Implementierung der SMS-Verifizierungsregistrierung. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und der Herausgeber wird Ihnen rechtzeitig antworten. Ich möchte mich auch bei Ihnen allen für Ihre Unterstützung der Script House-Website bedanken!