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 相关文章推荐
第五节 克隆 [5]
Oct 09 PHP
在任意字符集下正常显示网页的方法二(续)
Apr 01 PHP
《PHP编程最快明白》第二讲 数字、浮点、布尔型、字符串和数组
Nov 01 PHP
新手学习PHP的一些基础知识分享
Jul 27 PHP
PHP 设计模式之观察者模式介绍
Feb 22 PHP
php文件操作实例代码
May 10 PHP
php在window iis的莫名问题的测试方法
May 14 PHP
PHP常用的缓存技术汇总
May 05 PHP
摘自织梦CMS的HTTP文件下载类
Aug 08 PHP
PHP排序算法之基数排序(Radix Sort)实例详解
Apr 21 PHP
Laravel5框架添加自定义辅助函数的方法
Aug 01 PHP
Laravel 不同生产环境服务器的判断实践
Oct 15 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
关于时间计算的结总
2006/12/06 PHP
PHP 解决utf-8和gb2312编码转换问题
2010/03/18 PHP
几个有用的php字符串过滤,转换函数代码
2012/05/01 PHP
jQuery 动画弹出窗体支持多种展现方式
2010/04/29 Javascript
jQuery照片伸缩效果不影响其他元素的布局
2014/05/09 Javascript
jQuery仿天猫实现超炫的加入购物车
2015/05/04 Javascript
JavaScript小技巧整理
2015/12/30 Javascript
在JavaScript中使用JSON数据
2016/02/15 Javascript
两种方法解决javascript url post 特殊字符转义 + &amp; #
2016/04/13 Javascript
Javascript实现图片懒加载插件的方法
2016/10/20 Javascript
微信小程序实现拖拽 image 触摸事件监听的实例
2017/08/17 Javascript
jQueryUI Sortable 应用Demo(分享)
2017/09/07 jQuery
Vue2 SSR渲染根据不同页面修改 meta
2017/11/20 Javascript
AngularJS 前台分页实现的示例代码
2018/06/07 Javascript
jQuery-ui插件sortable实现自由拖动排序
2018/12/01 jQuery
Javascript基于OOP实实现探测器功能代码实例
2020/08/26 Javascript
vue使用canvas实现移动端手写签名
2020/09/22 Javascript
[02:44]完美大师赛主赛事淘汰赛第二日观众采访
2017/11/24 DOTA
Python中的True,False条件判断实例分析
2015/01/12 Python
python继承和抽象类的实现方法
2015/01/14 Python
python使用BeautifulSoup分析网页信息的方法
2015/04/04 Python
深入理解Python分布式爬虫原理
2017/11/23 Python
pip install urllib2不能安装的解决方法
2018/06/12 Python
Python简单爬虫导出CSV文件的实例讲解
2018/07/06 Python
python3.x+pyqt5实现主窗口状态栏里(嵌入)显示进度条功能
2019/07/04 Python
选择Python写网络爬虫的优势和理由
2019/07/07 Python
python 制作python包,封装成可用模块教程
2020/07/13 Python
canvas绘制文本内容自动换行的实现代码
2019/01/14 HTML / CSS
BRASTY捷克:购买香水、化妆品、手袋和手表
2017/07/12 全球购物
Spartoo美国:欧洲排名第一的在线时装零售商
2019/12/12 全球购物
函授本科个人自我鉴定
2014/03/25 职场文书
干部作风建设年活动剖析材料
2014/10/23 职场文书
仓库保管员岗位职责
2015/02/09 职场文书
2015年药房工作总结
2015/04/25 职场文书
导游词之上海豫园
2019/10/24 职场文书
Apache Hudi 加速传统的批处理模式
2022/04/24 Servers