Laravel实现短信注册的示例代码


Posted in PHP onMay 29, 2018

正在公司做一个商城项目,由于只有一个后台,所以注册用短信注册也就轮到我来做的。刚刚开始,我内心还是有点虚的,还好有 Laravel-china 社区的 summer 大神,写的书。在里面参考了它的写法和思路,并且用了 easy-sms 包,这才用了半个下午的时间,顺利的做出来了,晚上赶紧和大家分享一波了。

1、确定短信运营商

我看到大佬都是用的云片,我也就毫不犹豫的大力推荐公司用这个短信平台了,不过其他的也可以咯。

首先自己注册一个帐号,然后找到这个

Laravel实现短信注册的示例代码 

点击开始接入,完成新手引导过程。

Laravel实现短信注册的示例代码 

第二部的签名和模板必须填写,类似我下面填写的这样

Laravel实现短信注册的示例代码 

Laravel实现短信注册的示例代码

值得注意的是这个模板必须和你到时候用 easy-sms 包的时候,设定的短信内容必须和这个一模一样,不然会报错的。

还有就是记得一定得拿到APIKEY。到时候,在env里进行配置。

# 云片
YUNPIAN_API_KEY=9c60bdd**********

2、安装 easy-sms

利用这个包,可以快速的实现短信发送功能。

composer require "overtrue/easy-sms"

由于该组件还没有 Laravel 的 ServiceProvider ,为了方便使用,我们可以自己封装一下。

首先在 config 目录中增加 easysms.php 文件

config/easysms.php 填写如下内容。

<?php
return [
 // HTTP 请求的超时时间(秒)
 'timeout' => 5.0,

 // 默认发送配置
 'default' => [
  // 网关调用策略,默认:顺序调用
  'strategy' => \Overtrue\EasySms\Strategies\OrderStrategy::class,

  // 默认可用的发送网关
  'gateways' => [
   'yunpian',
  ],
 ],
 // 可用的网关配置
 'gateways' => [
  'errorlog' => [
   'file' => '/tmp/easy-sms.log',
  ],
  'yunpian' => [
   'api_key' => env('YUNPIAN_API_KEY'),
  ],
 ],
];

然后创建一个 ServiceProvider

php artisan make:provider EasySmsServiceProvider

修改文件 app/providers/EasySmsServiceProvider.php

<?php

namespace App\Providers;

use Overtrue\EasySms\EasySms;
use Illuminate\Support\ServiceProvider;

class EasySmsServiceProvider extends ServiceProvider
{
 /**
  * Bootstrap the application services.
  *
  * @return void
  */
 public function boot()
 {
  //
 }

 /**
  * Register the application services.
  *
  * @return void
  */
 public function register()
 {
  $this->app->singleton(EasySms::class, function ($app) {
   return new EasySms(config('easysms'));
  });

  $this->app->alias(EasySms::class, 'easysms');
 }
}

最后在 config/app.phpproviders 里增加刚刚创建的服务写进去,App\Providers\EasySmsServiceProvider::class,

App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,

App\Providers\EasySmsServiceProvider::class, //easy-sms

3、创建路由和对应的控制器

首先创建路由,我们需要一个ajax请求短信验证码的方法,和一个进行确认注册的逻辑方法,如下:

Route::group(['prefix' => 'verificationCodes', 'as' => 'verificationCodes.'], function() {
  Route::post('register', 'VerificationCodesController@register')->name('register');
  Route::get('ajaxregister', 'VerificationCodesController@ajaxregister')->name('ajaxregister');
 });

路由创建好了,我们用命令生成controller了

php artisan make:controller Home\VerificationCodesController

再直接在里面写 registerajaxregister 方法了

代码逻辑

修改文件

app/Home/VerificationCodesController.php

<?php
.
.
.
use Overtrue\EasySms\EasySms;
use App\Models\System\User;
class VerificationCodesController extends Controller
{
 // 这里验证就不写了。
 public function ajaxregister(VerificationCodeRequest $request, EasySms $easySms)
 {
  //获取前端ajax传过来的手机号
  $phone = $request->phone;
  
  // 生成4位随机数,左侧补0
  $code = str_pad(random_int(1, 9999), 4, 0, STR_PAD_LEFT);
  
  try {
   $result = $easySms->send($mobile, [
    'content' => "【安拾商城】您的验证码是{$code}。如非本人操作,请忽略本短信"
   ]);
  } catch (Overtrue\EasySms\Exceptions\NoGatewayAvailableException $exception) {
   $response = $exception->getExceptions();
   return response()->json($response);
  }
  
  //生成一个不重复的key 用来搭配缓存cache判断是否过期
  $key = 'verificationCode_' . str_random(15);
  $expiredAt = now()->addMinutes(10);
  
  // 缓存验证码 10 分钟过期。
  \Cache::put($key, ['mobile' => $mobile, 'code'=> $code], $expiredAt);
  
  return response()->json([
   'key' => $key,
   'expired_at' => $expiredAt->toDateTimeString(),
  ], 201);
 }

这样,用户就能收到短信,并且前端应该保存这个 key ,提交注册表单的时候传递给后台,判断是否已经过期。下面就是判断是否过期,验证码是否错误。

public function register(VerificationCodeRequest $request)
{
 //获取刚刚缓存的验证码和key
 $verifyData = \Cache::get($request->verification_key);
 
 //如果数据不存在,说明验证码已经失效。
 if(!$verifyData) {
  return response()->json(['status' =>0, 'message'=> '短信验证码已失效'], 422);
 }
 
 // 检验前端传过来的验证码是否和缓存中的一致
 if (!hash_equals($verifyData['code'], $request->verification_code) {
  return redirect()->back()->with('warning', '短信验证码错误');
 }
 
 $user = User::create([
  'mobile' => $verifyData['mobile'],
  'password' => bcrypt($request->password),
 ]);

 // 清除验证码缓存
 \Cache::forget($request->verification_key);

 return redirect()->route('login')->with('success', '注册成功!');
 
}

上面的 hash_equals 是可防止时序攻击的字符串比较的~

以上就是我整个的过程。

PHP 相关文章推荐
自动把纯文本转换成Web页面的php代码
Aug 27 PHP
PHP Zip解压 文件在线解压缩的函数代码
May 26 PHP
php入门学习知识点二 PHP简单的分页过程与原理
Jul 14 PHP
php 无法加载mysql的module的时候的配置的解决方案引发的思考
Jan 27 PHP
php实现的漂亮分页方法
Apr 17 PHP
PHP安全的URL字符串base64编码和解码
Jun 19 PHP
基于递归实现的php树形菜单代码
Nov 19 PHP
彻底删除thinkphp3.1案例blog标签的方法
Dec 05 PHP
PHP中把数据库查询结果输出为json格式简单实例
Apr 09 PHP
php异常处理方法实例汇总
Jun 24 PHP
微信自定义分享php代码分析
Nov 24 PHP
thinkPHP中配置的读取与C方法详解
Dec 05 PHP
PHP abstract 抽象类定义与用法示例
May 29 #PHP
thinkPHP中U方法加密传递参数功能示例
May 29 #PHP
在Laravel中使用DataTables插件的方法
May 29 #PHP
ThinkPHP实现的rsa非对称加密类示例
May 29 #PHP
PHP中实现中文字串截取无乱码的解决方法
May 29 #PHP
php实现表单提交上传文件功能
May 28 #PHP
PHP封装的非对称加密RSA算法示例
May 28 #PHP
You might like
PHP对接微信公众平台消息接口开发流程教程
2014/03/25 PHP
PHP ignore_user_abort函数详细介绍和使用实例
2014/07/15 PHP
PHP下使用mysqli的函数连接mysql出现warning: mysqli::real_connect(): (hy000/1040): ...
2016/02/14 PHP
jquery.validate使用攻略 第二部
2010/07/01 Javascript
js页面跳转常用的几种方式
2010/11/25 Javascript
jquery uaMatch源代码
2011/02/14 Javascript
修改js Calendar日历控件 兼容IE9/谷歌/火狐
2013/01/04 Javascript
jQuery 关于伪类选择符的使用说明
2013/04/24 Javascript
JS截取与分割字符串常用技巧总结
2015/11/10 Javascript
js实现继承的5种方式
2015/12/01 Javascript
Bootstrap响应式侧边栏改进版
2016/09/17 Javascript
jQuery简单倒计时效果完整示例
2016/09/20 Javascript
javascript函数的四种调用模式
2017/01/08 Javascript
vue 2.0路由之路由嵌套示例详解
2017/05/08 Javascript
node+express框架中连接使用mysql(经验总结)
2018/11/10 Javascript
JS获取月的第几周和年的第几周实例代码
2018/12/05 Javascript
JavaScript实现预览本地上传图片功能完整示例
2019/03/08 Javascript
微信小程序云开发之云函数详解
2019/05/16 Javascript
微信小程序tabBar设置实例解析
2019/11/14 Javascript
HTML元素拖拽功能实现的完整实例
2020/12/04 Javascript
js 执行上下文和作用域的相关总结
2021/02/08 Javascript
解决Python中定时任务线程无法自动退出的问题
2019/02/18 Python
python调用并链接MATLAB脚本详解
2019/07/05 Python
python实现while循环打印星星的四种形状
2019/11/23 Python
前端制作动画的几种方式(css3,js)
2016/12/12 HTML / CSS
英国最大的电子零件及配件零售商:Partmaster
2017/04/24 全球购物
水果连锁超市创业计划书
2014/01/24 职场文书
2014年公务员思想汇报范文:全心全意为人民服务
2014/03/06 职场文书
《一个小村庄的故事》教学反思
2014/04/13 职场文书
公司离职证明标准范本
2014/10/05 职场文书
优秀教师先进事迹材料
2014/12/15 职场文书
司机个人年终总结
2015/03/03 职场文书
小学安全教育主题班会
2015/08/12 职场文书
Python超简单容易上手的画图工具库推荐
2021/05/10 Python
redis requires ruby version2.2.2的解决方案
2021/07/15 Redis
windows server2008 开启端口的实现方法
2022/06/25 Servers