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 相关文章推荐
初次接触php抽象工厂模式(Elgg)
Mar 21 PHP
thinkphp3.0 模板中函数的使用
Nov 13 PHP
Yii PHP Framework实用入门教程(详细介绍)
Jun 18 PHP
在PHP上显示JFreechart画的统计图方法
Nov 03 PHP
php动态函数调用方法
May 21 PHP
PHP计算日期相差天数实例分析
Feb 23 PHP
php实现批量修改文件名称的方法
Jul 23 PHP
浅谈php中的访问修饰符private、protected、public的作用范围
Nov 20 PHP
Laravel5.* 打印出执行的sql语句的方法
Jul 24 PHP
PHP实现求解最长公共子串问题的方法
Nov 17 PHP
PHP自定义错误处理的方法分析
Dec 19 PHP
详解PHP实现支付宝小程序用户授权的工具类
Dec 25 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
php5.4以上版本GBK编码下htmlspecialchars输出为空问题解决方法汇总
2015/04/03 PHP
WordPress JQuery处理沙发头像
2009/06/22 Javascript
js实现全屏漂浮广告移入光标停止移动
2013/12/02 Javascript
node.js中的fs.closeSync方法使用说明
2014/12/17 Javascript
jQuery表单美化插件jqTransform使用详解
2015/04/12 Javascript
JS实现黑色风格的网页TAB选项卡效果代码
2015/10/09 Javascript
angular实现表单验证及提交功能
2017/02/01 Javascript
vue.js指令和组件详细介绍及实例
2017/04/06 Javascript
JavaScript数据类型的存储方法详解
2017/08/25 Javascript
react-native使用react-navigation进行页面跳转导航的示例
2017/09/07 Javascript
jQuery中ajax获取数据赋值给页面的实例
2017/12/31 jQuery
react 兄弟组件如何调用对方的方法示例
2018/10/23 Javascript
vue+Vue Router多级侧导航切换路由(页面)的实现代码
2018/12/20 Javascript
ElementUI Tag组件实现多标签生成的方法示例
2019/07/08 Javascript
JS常见错误(Error)及处理方案详解
2020/07/02 Javascript
JQuery通过键盘控制键盘按下与松开触发事件
2020/08/07 jQuery
vue组件开发之tab切换组件使用详解
2020/08/21 Javascript
VUE : vue-cli中去掉路由中的井号#操作
2020/09/04 Javascript
[01:06:30]DOTA2-DPC中国联赛定级赛 Phoenix vs DLG BO3第二场 1月9日
2021/03/11 DOTA
详解设计模式中的工厂方法模式在Python程序中的运用
2016/03/02 Python
详解Python编程中对Monkey Patch猴子补丁开发方式的运用
2016/05/27 Python
python运行时强制刷新缓冲区的方法
2019/01/14 Python
python实现支付宝转账接口
2019/05/07 Python
Python使用numpy模块实现矩阵和列表的连接操作方法
2019/06/26 Python
Flask-WTF表单的使用方法
2019/07/12 Python
通俗讲解python 装饰器
2020/09/07 Python
canvas探照灯效果的示例代码
2018/11/30 HTML / CSS
HTML5实现移动端弹幕动画效果
2019/08/01 HTML / CSS
ProBikeKit德国:在线公路自行车专家
2018/06/03 全球购物
世界领先的豪华床上用品供应商之一:Bedeck Home
2019/03/18 全球购物
Jones Bootmaker官网:优质靴子和鞋子在线
2020/11/30 全球购物
介绍一些UNIX常用简单命令
2014/11/11 面试题
农村婚礼主持词
2014/03/13 职场文书
村干部培训班主持词
2014/03/28 职场文书
夫妻双方自愿离婚协议书怎么写
2014/12/01 职场文书
asyncio异步编程之Task对象详解
2022/03/13 Python