侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Thinkphp实现短信验证注册功能

ThinkPHP  /  管理员 发布于 9年前   205

前言

注册时经常需要用到短信验证码,本文记录一下思路和具体实现。

短信验证平台使用云片,短信验证码的生成使用thinkphp。

思路

1、用户输入手机号,请求获取短信验证码。

2、thinkphp生成短信验证码,存储,同时和其他参数一起发送请求给云片。

3、云片发送短信验证码到指定手机号。

4、用户输入短信验证码。

5、thinkphp根据验证码是否正确、验证码是否过期两个条件判断是否验证通过。

代码实现

验证接口

接口地址:https://sms.yunpian.com/v1/sms/send.json。

使用postman,输入三个必须的参数apikey、mobile和text。

php发起http/https请求

使用php的curl函数发起https请求,带入参数apikey、mobile和text。

// 获取短信验证码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;}

生成随机短信验证码

默认生成四位的随机短信验证码。

// 生成短信验证码public function createSMSCode($length = 4){$min = pow(10 , ($length - 1));$max = pow(10, $length) - 1;return rand($min, $max);}

整合

在数据库新建表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代码:// 获取短信验证码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);}}}}}

验证短信验证码

验证短信验证码时间是否过期,验证短信验证码是否正确。

// 验证短信验证码是否有效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); //60sif($period>=0 && $period<=20){return true;}else{return false;}}

改进

为了防止短信轰炸,在请求获取短信验证码时,需要加入图片验证码。

thinkphp提供了生成图片验证码的函数,下面我们来实现验证码的生成、刷新和验证。

生成和刷新图片验证码

// 获取图片验证码,刷新图片验证码public function getPicCode(){$config = array('fontSize'=>30, // 验证码字体大小'length'=>4, // 验证码位数'useNoise'=>false, // 关闭验证码杂点'expire'=>600);$Verify = new \Think\Verify($config);$Verify->entry(2333);//2333是验证码标志}

假设,该函数的对应url为http://localhost/owner-bd/index.php/Home/CheckCode/getPicCode,那么,图片验证码的地址就是这个url,放入页面图片标签的src属性即可。

验证图片验证码

// 验证验证码是否正确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);};}

以上方法,我们利用了thinkphp提供的check方法,实现起来很简单。但是,如果想要得到验证细节,就没有办法了。比如,验证码错误,可能验证码超时,可能因为输入验证码错误,可能因为验证码已经使用过等等。必要的时候,可以重写thinkphp的验证码类,或者重写thinkphp的check方法。

跑通前后端

后端修改

验证图片验证码函数,改为被调用函数:

public function checkPicCode($picCode){$verify = new \Think\Verify();if($verify->check($picCode, 2333)){return true;}else{return false;};}

在获取短信验证码函数的最顶部,添加调用图片验证码函数,只有通过验证,才发送请求给云片。

// 获取短信验证码public function getSMSCode(){$picCode = $_POST['picCode'];if(!$this->checkPicCode($picCode)){$result = array('code' => '1','ext' => '验证码错误,请重新输入');echo json_encode($result,JSON_UNESCAPED_UNICODE);return;}/*省略*/}

前端核心代码

注册
// register.jsangular.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();}});

优化

以上代码,安全性不是很好,我们可以利用工具绕过前端验证。为了避免这个问题,可以在checkPicCode和checkSMSCode函数中添加session值来标记。

$_SESSION['checkPicCode'] = true;$_SESSION['checkSMSCode'] = true;

在最后一步,向数据库中添加用户时,先验证一下两个session值是否都为true,都为true时再添加。

成果

后记

以后也许有用的代码:

echo json_encode($_SESSION);// 打印出session中的数据echo session_id();// 打印当前session的id

以上所述是小编给大家介绍的Thinkphp实现短信验证注册,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对站的支持!

您可能感兴趣的文章:

  • thinkPHP3.2.3实现阿里大于短信验证的方法
  • ThinkPHP验证码使用简明教程
  • thinkphp验证码显示不出来的解决方法
  • thinkPHP中验证码的简单使用方法
  • thinkphp3.2点击刷新生成验证码
  • 详解ThinkPHP3.2.3验证码显示、刷新、校验
  • thinkphp自带验证码全面解析
  • ThinkPHP验证码和分页实例教程
  • ThinkPHP3.2.1图片验证码实现方法
  • thinkPHP框架实现的短信接口验证码功能示例


  • 上一条:
    在Thinkphp中使用ajax实现无刷新分页的方法
    下一条:
    基于thinkPHP框架实现留言板的方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • thinkphp + mongodb项目中数据加载慢问题分析及解决(0个评论)
    • thinkphp6框架中封装redis操作类(0个评论)
    • thinkphp6框架中实现定时任务功能流程步骤(0个评论)
    • Thinkphp5.1框架中实现Session+Redis会话共享流程步骤(0个评论)
    • TP5框架版本5.0.10安全漏洞根据官方补丁修复,也是本站安全漏洞修复(0个评论)
    • 近期文章
    • 在go语言中实现字符串可逆性压缩及解压缩功能(0个评论)
    • 使用go + gin + jwt + qrcode实现网站生成登录二维码在app中扫码登录功能(0个评论)
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-12
    • 2018-01
    • 2018-02
    • 2020-03
    • 2021-07
    • 2021-12
    • 2022-05
    • 2022-06
    • 2022-09
    • 2023-01
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客