laravel中使用获取手机验证码绑定手机号

我使用的是阿里云的短信包。
如果是让我们直接写短信扩展发送的话,工作量是非常大的,所以,我使用的是外部扩展包
packagist中搜索sms
我使用的是这一个
laravel中使用获取手机验证码绑定手机号_第1张图片
安装命令

composer require overtrue/easy-sms

这是一款满足你的多种发送需求的短信发送组件,支持多家平台的手机短信组件

首先,第一时间去申请阿里云短信签名和模板(大坑比来着)
laravel中使用获取手机验证码绑定手机号_第2张图片
短信模板
laravel中使用获取手机验证码绑定手机号_第3张图片

然后去使用下载的类库把

use Overtrue\EasySms\EasySms;

$config = [
    // HTTP 请求的超时时间(秒)
    'timeout' => 5.0,

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

        // 默认可用的发送网关
        'gateways' => [
             'aliyun',
        ],
    ],
    // 可用的网关配置
    'gateways' => [
        'errorlog' => [
            'file' => '/tmp/easy-sms.log',
        ],
        'aliyun' => [
            'access_key_id' => '',//阿里云的access_key_id
            'access_key_secret' => '',//阿里云的access_key_secret
            'sign_name' => '',//阿里云的签名
        ],
        //...
    ],
];

$easySms = new EasySms($config);

$easySms->send(13188888888, [
    'template' => 'SMS_001',//短信模板名
    'data' => [
        'code' => 6379//这里可以随机生成数
    ],
]);

值得注意的是,阿里云的access_key_id和access_key_secret要使用子用户组的,不能使用主组的,因为很危险

然后,去创建一个子用户
laravel中使用获取手机验证码绑定手机号_第4张图片
创建成功后
在这里插入图片描述
还需要给这个用户权限
laravel中使用获取手机验证码绑定手机号_第5张图片
添加了权限后就可以使用这个用户来调用API了

一般情况下,是不是要用到手机验证的地方非常多?
所以,我们可以将手机验证码类拆分来
首先,先将发生验证码的配置信息拆分出来

1.在config配置目录下新建一个配置文件,里面存放的是发生验证码的配置信息
laravel中使用获取手机验证码绑定手机号_第6张图片
代码:


//短信发送配置信息
return $config = [
    // HTTP 请求的超时时间(秒)
    'timeout' => 5.0,

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

        // 默认可用的发送网关
        'gateways' => [
            'aliyun',
        ],
    ],
    // 可用的网关配置
    'gateways' => [
        'errorlog' => [
            'file' => '/tmp/easy-sms.log',
        ],
        'aliyun' => [
            'access_key_id' => env('SMS_AK'),
            'access_key_secret' => env('SMS_SK'),
            'sign_name' => '小信PHP',//阿里云签名的名字
        ],
        //...
    ],
    //短信模板
    'template' => 'SMS_224341459',//模板名
];

里面的env(‘SMS_AK’)是什么意思呢?

由于,如果我们把代码放到GitHub里面,这个配置文件也会放到上面,那么,这不是暴露了我的秘钥了吗?所以,我把它放在.env文件中,因为.env文件是不会被发布到GitHub上面的

这些都是不会被发布的文件
laravel中使用获取手机验证码绑定手机号_第7张图片

所以,env(‘SMS_AK’)被我放到了.env中,来看看

laravel中使用获取手机验证码绑定手机号_第8张图片

配置文件处理好后,就是来处理控制验证码的发送了
竟然说了手机验证码的方式在很多地方都会用到,那么就来使用事件
使用了事件,可以在我们需要的地方直接去调用它就好了
事件的注册在app\Providers\EventServiceProvider.php中,去$listen数组里面来注册一个事件,
这里定义一个SendSms事件,值得注意的是事件名SendSms要和SendSmsListener监听者名字不一样才可以
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
‘App\Events\SendSms’ => [
‘App\Listeners\SendSmsListener’,
],
];
定义好事件后,去执行添加事件命令,这个命令会自动检测事件文件,如果存在没有添加的事件文件,就会自动帮我生成事件文件

php artisan event:generate

执行该命令后,会在app\Listeners监听者目录app\Events事件目录生成两个文件
laravel中使用获取手机验证码绑定手机号_第9张图片
因为我们定义的事件里面定义了监听者
laravel中使用获取手机验证码绑定手机号_第10张图片
所以,到时候是会触发监听者的,所以,我们把代码写在监听者文件里面

public function handle(SendSms $event)
    {
        //发送验证码到手机
        $config = config('sms');
        $easySms = new EasySms($config);
        //随机生成验证码
        $code = mt_rand(1000, 9999);
        //缓存验证码
        Cache::put('phone_code_' . $event->phone, $code, now()->addMinutes(5));
        try {
            $easySms->send($event->phone, [
                'template' => $config['template'],
                'data' => [
                    'code' => $code,
                ],
            ]);
        } catch (\Exception $e) {
            return $e->getExceptions();
        }
    }

那么代码里面的$event是哪里来的呢?就是刚刚我们生成了事件,
laravel中使用获取手机验证码绑定手机号_第11张图片
这个属性就是我们在调用事件的时候传递给它的

控制器文件BindController

 /*
    * 获取手机验证码
    */
    public function phoneCode(Request $request)
    {
        $request->validate([
            'phone' => 'required|regex:/^1[3-9]\d{9}$/'
        ]);
        //发送短信事件
        SendSms::dispatch($request->input('phone'));

        return $this->response->noContent();
    }

确认验证码

/*
     * 更新手机号
     */
    public function updatePhone(Request $request)
    {

        //更新用户手机号
        $user = auth('api')->user();//获取用户对象
        $user->phone = $request->input('phone');//获取用户输入的邮箱
        $user->save();//保存邮箱到数据库
        return $this->response->noContent();
    }

???,那么,这个确认验证码的验证去哪里了呢?
由于用到确认验证码的地方非常多,所以,我需要中间件来使用它,
因为,如果连中间件都过不了,也就进不来我们的控制器方法了。
那么,是如何让中间件在控制器中生效的呢?(以前写过在路由中)

来,写一个构造方法,每次执行进来控制器都去执行一下控制器

public function __construct()
    {
        //使用路由中间件
        $this->middleware(['check.phone.code'])->only(['updatePhone']);
    }

中间件是需要在app\Http\Kernel.php中注册才可以使用,check.phone.code这个名字也是在里面注册的

protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'check.permission' => \App\Http\Middleware\CheckPermission::class,//用户权限中间件
        'check.phone.code' => \App\Http\Middleware\CheckPhoneCode::class,//手机号验证中间件
        'check.email.code' => \App\Http\Middleware\CheckEmailCode::class,//邮箱验证中间件
    ];

好了,这样就可以发送验证码并且可以验证了

你可能感兴趣的:(PHP,laravel,laravel,php)