概述

在做项目的时候,需要用到短信发送验证码功能。不能不说Yii2的牛逼,很容易就搞定了。下面我整理一下具体功能和流程,分享给大家。

主要功能

  • 通过Yii2 rules验证手机号
  • 通过js验证是否为手机号
  • 通过Ajax验证手机是否在数据库存在
  • 通过ajax发送短信验证码
  • Js倒计时功能(cookie保存信息,防刷新)
  • 通过Yii2 rules 验证手机短信码是否合法。

实现详细步骤和代码

前端表单设计,这里主要定义了手机号码filed和和发送短信的按钮 'id' =>'second'

<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'loginMode')->hiddenInput(['value' => 'login_sms_code'])->label(false); ?>
<div class="form-group has-feedback login-mobile f-left">
<?= $form->field($model, 'mobile')->textInput(['placeholder' => $model->getAttributeLabel('mobile')])->label(false) ?>
<span class="glyphicon glyphicon-phone form-control-feedback"></span>
</div>
<?= Html::buttonInput(Yii::t('app', 'Get SMS Code'), ['class' => 'btn bg-yellow ', 'name' => 'signup-button', 'id' => 'second']) ?>
<div class="clear"></div>
<div class="form-group has-feedback">
<?= $form->field($model, 'smsCode')->textInput(['placeholder' => $model->getAttributeLabel('smsCode')])->label(false) ?>
<span class="glyphicon glyphicon-mobile form-control-feedback"></span>
</div>
<div class="footer bg-gray">
<?= Html::submitButton(Yii::t('app', 'Login'), ['class' => 'btn bg-blue btn-block']) ?>
</div>
<?php ActiveForm::end(); ?>

当发送短信的按钮 'id'=>'second' 被点击后,会通过js验证手机的合法性,然后发送短信,并进行倒计时。具体js部分代码如下

/发送验证码时添加cookie
function addCookie(name,value,expiresHours){
var cookieString=name+"="+escape(value);
//判断是否设置过期时间,0代表关闭浏览器时失效
if(expiresHours>0){
var date=new Date();
date.setTime(date.getTime()+expiresHours*1000);
cookieString=cookieString+";expires=" + date.toUTCString();
}
document.cookie=cookieString;
}
//修改cookie的值
function editCookie(name,value,expiresHours){
var cookieString=name+"="+escape(value);
if(expiresHours>0){
var date=new Date();
date.setTime(date.getTime()+expiresHours*1000); //单位是毫秒
cookieString=cookieString+";expires=" + date.toGMTString();
}
document.cookie=cookieString;
}
//根据名字获取cookie的值
function getCookieValue(name){
var strCookie=document.cookie;
var arrCookie=strCookie.split("; ");
for(var i=0;i<arrCookie.length;i++){
var arr=arrCookie[i].split("=");
if(arr[0]==name){
return unescape(arr[1]);
break;
}
} } $(function(){
$("#second").click(function (){
sendCode($("#second"));
});
v = getCookieValue("secondsremained_login") ? getCookieValue("secondsremained_login") : 0;//获取cookie值
if(v>0){
settime($("#second"));//开始倒计时
}
})
//发送验证码
function sendCode(obj){
var site = 'http://yun.ucrm.com.cn/';
var mobile = $("#loginform-mobile").val();
//检查手机是否合法
var result = isPhoneNum();
if(result){
//检查手机号码是否存在
var exists_result = dbCheckMobileExists(site+'site/check-mobile-exists',{"mobile":mobile});
if(exists_result){
doPostBack(site+'sms/send-login-code',{"mobile":mobile});
addCookie("secondsremained_login",60,60);//添加cookie记录,有效时间60s
settime(obj);//开始倒计时
}
}
} //检查手机号码是否存在
function dbCheckMobileExists(url,queryParam){
$.ajax({
async : false,
cache : false,
type : 'POST',
url : url,// 请求的action路径
data:queryParam,
error : function() {// 请求失败处理函数
},
success:function(result){
if(result=='Success'){
return true;
}
else{
alert('该手机号码不存在!');
return false;
}
}
});
}
//将手机利用ajax提交到后台的发短信接口
function doPostBack(url,queryParam) {
$.ajax({
async : false,
cache : false,
type : 'POST',
url : url,// 请求的action路径
data:queryParam,
error : function() {// 请求失败处理函数
},
success:function(result){
if(result=='Success'){
alert('短信发送成功,验证码10分钟内有效,请注意查看手机短信。如果未收到短信,请在60秒后重试!');
}
else{
alert('短信发送失败,请和网站客服联系!');
return false;
}
}
});
} //开始倒计时
var countdown;
function settime(obj) {
countdown=getCookieValue("secondsremained_login") ? getCookieValue("secondsremained_login") : 0;
if (countdown ==0) {
obj.removeAttr("disabled");
obj.val("获取验证码");
return;
} else {
obj.attr("disabled", true);
obj.val(countdown + "秒后重发");
countdown--;
editCookie("secondsremained_login",countdown,countdown+1);
}
setTimeout(function() { settime(obj) },1000) //每1000毫秒执行一次
}
//校验手机号是否合法
function isPhoneNum(){
var phonenum = $("#loginform-mobile").val();
var myreg = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\d{8})$/;
if(!myreg.test(phonenum)){
alert('请输入有效的手机号码!');
$("#loginform-mobile").focus();
return false;
}else{
return true;
}
}

上述代码中有两个方法是通过Ajax交互的,一个为验证手机是否合法的方法dbCheckMobileExists(),另一个是通过ajax发送短信码的方法doPostBack(). 具体每个方法的代码大家上面看就可以了。 dbCheckMobileExists()会提交到CheckMobileExists方法检查手机是否存在:

public function actionCheckMobileExists()
{
$mobile = Yii::$app->request->post('mobile');
if(User::findByMobile($mobile)){
echo 'Success';
}else{
echo 'Failed';
}
}

doPostBack()会提交到SendLoginCode方法发送登录验证码:

public function actionSendLoginCode()
{
$mobile = Yii::$app->request->post('mobile');
$code = $this->createCode();
$content = "本次验证码为".$code.",您正在登录纽仁云客管理系统,打死也不告诉别人哦";
if($this->send($mobile,$content)===true){
//检查session是否打开
if(!Yii::$app->session->isActive){
Yii::$app->session->open();
}
//验证码和短信发送时间存储session
Yii::$app->session->set('login_sms_code',$code);
Yii::$app->session->set('login_sms_time',time());
echo 'Success';
}else{
echo 'Failed';
}
}

在上述发送代码的时候,当发送成功时,会保存两个session,login_sms_code和login_sms_time,分别记录了验证码内容和生成时间。

当发送成功后,用户会收到验证码,然后输入后进行提交,此时我们会进行验证码的校验,这里我们是采用yii2 rules来完成此项任务。

在 LoginForm 表的里面的 rules 里面添加下面校验规则,大家可以看到这里写了关于手机和验证码的诸多验证规则,其实最后一个验证规则即为 验证短信码是否正确,这里我们通过requiredValue验证用户输入的值是否等于 getSmsCode 的值即可。

['mobile', 'required','on' => ['default','login_sms_code']],
['mobile', 'integer','on' => ['login_sms_code']],
['mobile','match','pattern'=>'/^1[0-9]{10}$/','on' => ['default','login_sms_code'],'message'=>'{attribute}必须为1开头的11位纯数字'],
['mobile', 'string', 'min'=>11,'max' => 11,'on' => ['default','login_sms_code']], ['smsCode', 'required','on' => ['default','login_sms_code']],
['smsCode', 'integer','on' => ['default','login_sms_code']],
['smsCode', 'string', 'min'=>6,'max' => 6,'on' => ['default','login_sms_code']],
['smsCode', 'required','requiredValue'=>$this->getSmsCode(),'on' => ['default','login_sms_code'],'message'=>'手机验证码输入错误'],

上面的getSmsCode()代码如下,这里通过session获取了验证码和生成时间,如果在10分钟内,则返回验证码session的值。

public function getSmsCode()
{
//检查session是否打开 if(!Yii::$app->session->isActive){
Yii::$app->session->open();
}
//取得验证码和短信发送时间session
$signup_sms_code = intval(Yii::$app->session->get('login_sms_code'));
$signup_sms_time = Yii::$app->session->get('login_sms_time');
if(time()-$signup_sms_time < 600){
return $signup_sms_code;
}else{
return 888888;
}
}

上面为全部代码,大家可以直接使用。

发短信模块使用的是 daixianceng/yii2-smser ,大家在gitbub上搜下安装即可。

代码还有改进的空间,判断手机号是否存在 和 是否合理 应该可以直接在 LoginForm 文件里面添加 rules 规则,然后 form 开启 Ajax 验证。就不需要自己手写 js 了。

来源地址:http://www.getyii.com/topic/221

Yii2发送短信验证码完全解决方案的更多相关文章

  1. java + maven 实现发送短信验证码功能

    如何使用java + maven的项目环境发送短信验证码,本文使用的是榛子云短信 的接口. 1. 安装sdk 下载地址: http://smsow.zhenzikj.com/doc/sdk.html ...

  2. 超实用的JavaScript代码段 Item4 --发送短信验证码

    发送短信验证码 实现点击“发送验证码”按钮后,按钮依次显示为“59秒后重试”.“58秒后重试”…直至倒计时至0秒时再恢复显示为“发送验证码”.在倒计时期间按钮为禁用状态 . 第一步.获取按钮.绑定事件 ...

  3. Laravel5中使用阿里大于(鱼)发送短信验证码

    在做用户注册和个人中心的安全管理时,我实现借助第三方短信平台(阿里大于(鱼))在Laravel框架中进行手机验证的设置:阿里大于,是阿里通信旗下优质便捷的云通信服务平台,整合了三大运营商的通信能力,为 ...

  4. 微信小程序发送短信验证码完整实例

    微信小程序注册完整实例,发送短信验证码,带60秒倒计时功能,无需服务器端.效果图: 代码: index.wxml <!--index.wxml--> <view class=&quo ...

  5. android发送短信验证码并自动获取验证码填充文本框

    android注册发送短信验证码并自动获取短信,截取数字验证码填充文本框. 一.接入短信平台 首先需要选择短信平台接入,这里使用的是榛子云短信平台(http://smsow.zhenzikj.com) ...

  6. java 阿里云接口实现发送短信验证码

    此刻自己做的小项目中,需要用到手机发送短信验证码实现注册功能,于是就去阿里云注册了账号,并实现随机发送验证码的功能 第一步:在阿里云官网登录注册   已有支付宝或淘宝的账号可以直接登录,最后需要实名认 ...

  7. Java 实现手机发送短信验证码

    Java 实现手机发送短信验证码 采用引入第三方工具的方式,网上查了半天,发现简单的实现方式便是注册一个中国网建的账号,新建账号的时候会附带赠几条免费短信,彩信 ,之后想要在使用就得花钱了.简单的操作 ...

  8. 阿里云短信服务发送短信验证码(JAVA开发此功能)

    开发此功能需注册阿里云账号,并开通短信服务(免费开通) 充值后,不会影响业务的正常使用!(因为发送验证类短信:1-10万范围的短信是0.045元/条).开发测试使用,充2块钱测试足够了 可参考阿里云官 ...

  9. java发送短信验证码的功能实现

    总结一下发送短信验证码的功能实现 (题外话:LZ是在腾讯云买的第三方(山东鼎信)短信服务平台的接口,1块钱20次的套餐来练手,哈哈,给他们打个广告,有需要的可以去购买哈,下面是购买链接短信服务平台购买 ...

随机推荐

  1. xUtils介绍 -- DbUtils、ViewUtils、HttpUtils、BitmapUtils

    转载注明出处:https://github.com/wyouflf/xUtils xUtils简单介绍 xUtils 包括了非常多有用的android工具. xUtils 支持大文件上传,更全面的ht ...

  2. Android 热修复使用Gradle Plugin1.5改造Nuwa插件

    随着谷歌的Gradle插件版本号的不断升级,Gradle插件如今最新的已经到了2.1.0-beta1,相应的依赖为com.android.tools.build:gradle:2.0.0-beta6, ...

  3. 【Excle数据透视表】如何重复显示行字段的项目标签

    前提:该数据透视表以表格形式显示 解决办法: 通过报表布局设置"重复所有项目标签" 修改前样式 步骤 单击数据透视表中任意单元格→设计→报表布局→重复所有项目标签 修改后样式

  4. charles用法详解

    Charles是目前最强大的http调试工具,在界面和功能上远强于Fiddler,同时是全平台支持,堪称圣杯级工具,唯一的缺陷是这货是收费的,而且是要¥50美元大洋…当然网上是有破解版的,鄙视下自己, ...

  5. 随想录(做自己代码的測试project师)

    [ 声明:版权全部.欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 非常多project师都有一个不好的习惯,由于大多数itproject师都喜欢写代码.可是不喜欢 ...

  6. Session和Cookie之间存在的区别与联系

    一. 概念理解 你可能有留意到当你浏览网页时,会有一些推送消息,大多数是你最近留意过的同类东西,比如你想买桌子,上淘宝搜了一下,结果连着几天会有各种各样的桌子的链接.这是因为 你浏览某个网页的时候,W ...

  7. C# const和static readonly区别

    [转]C# const和static readonly区别 以前只是知道Const和static readonlyd的区别在于const的值是在编译期间确定的,而static readonly是在运行 ...

  8. 闪屏(Splash)

    好久没弄ReactNative了, 写个怎样实现闪屏(Splash)的文章吧. 注意: (1) 怎样切换页面. (2) 怎样使用计时器TimerMixin. (3) 怎样使用动画效果. (4) 怎样载 ...

  9. cache和buffer区别探讨

    一. 1.Buffer(缓冲区)是系统两端处理速度平衡(从长时间尺度上看)时使用的.它的引入是为了减小短期内突发I/O的影响,起到流量整形的作用.比如生产者——消费者问题,他们产生和消耗资源的速度大体 ...

  10. day14—JQuery编程基础

    JQuery 1.什么是jQuery jQuery是一个优秀的JavaScript框架.一个轻量级的JavaScript类库.jQuery的核心理念是Write less.Do more. 使用jQu ...