一、绑定手机
1.1 创建绑定手机路由
$api->post('phone/code', [BindController::class, 'phoneCode']);
$api->post('phone/update', [BindController::class, 'updatePhone']);

1.2 短信开通配置
我们要使用手机验证码的功能,需要使用到第三方api ,我们这边以阿里云为例:   购买了短信的服务后,我们去添加签名:   添加完签名后,我们还需要去添加模版:   如果你是用RAM 创建的用户访问权限的话,那么需要给用户分配短信服务的权限
1.3 创建手机号字段
现在用户表里还没手机号字段,我们运行命令php artisan make:migration add_phone_to_users_table --table=users  写入:
Schema::table('users', function (Blueprint $table) {
$table->string('phone')->nullable()->after('email')->comment('手机号');
});
 运行迁移命令:php artisan migrate  
1.4 创建发送短信控制方法
我们使用第三方的包来进行开发:  运行命令composer require overtrue/easy-sms 来进行安装: 
发送手机验证码配置: 在.env 中配置access_key_id 和access_key_secret :
SMS_AK=
SMS_SK=

在config 文件下新建一个sms.php 写入:
<?php
return [
'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' => '',
],
],
'template' => $config['template'],
];

在BindController.php 中写入发送短信和更新手机号的方法,发送短信我们使用事件: 在Providers/EventServiceProvider.php 中配置事件和监听者:
'App\Events\SendSms' => [
'App\Listeners\SendSmsListener',
],
 运行命令php artisan event:generate 生成事件和监听者:    
在SendSmsListener.php 监听者中写入:
<?php
namespace App\Listeners;
use App\Events\SendSms;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Cache;
use Overtrue\EasySms\EasySms;
class SendSmsListener implements ShouldQueue
{
public function __construct()
{
}
public function handle(SendSms $event)
{
$config = config('sms');
$easySms = new EasySms($config);
$code = rand(0000, 9999);
Cache::put($event->phone, $code, now()->addMinutes(5));
$easySms->send($event->phone, [
'template' => $config['template'],
'data' => [
'code' => $code,
'product' => $event->product
],
]);
}
}
创建一个验证手机验证码是否正确的中间件(邮箱的话也可以创建中间件,因为邮箱可能也不止一处地方需要验证): 运行命令:php artisan make:middleware CheckPhoneCode  写入验证的代码:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class CheckPhoneCode
{
public function handle(Request $request, Closure $next)
{
$request->validate([
'phone' => 'required|regex:/^1[3-9]\d{9}',
'code' => 'required'
], [
'code.required' => "验证码不能为空",
]);
if (cache($request->input('phone')) != $request->input('code')) {
abort(400, '验证码或手机号错误!');
}
return $next($request);
}
}
 然后在Kernal.php 中去注册中间件:
'check.phone' => \App\Http\Middleware\CheckPhoneCode::class,
 因为目前只对一个方法进行控制验证,所以没有必要放到路由中去,我们可以直接在控制器方法中去验证验证码是否正确:
public function __construct()
{
$this->middleware(['check.phone'])->only(['updatePhone']);
}

控制器方法:
<?php
namespace App\Http\Controllers\Auth;
use App\Events\SendSms;
use App\Http\Controllers\BaseController;
use App\Mail\SendEmailCode;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Overtrue\EasySms\EasySms;
class BindController extends BaseController
{
public function __construct()
{
$this->middleware(['check.phone'])->only(['updatePhone']);
}
public function emailCode(Request $request)
{
$request->validate([
'email' => 'required|email'
]);
Mail::to($request->input('email'))->queue(new SendEmailCode($request->input('email')));
return $this->response->noContent();
}
public function updateEmail(Request $request)
{
$request->validate([
'email' => 'required|email',
'code' => 'required'
], [
'code.required' => "验证码不能为空",
]);
if (cache($request->input('email')) != $request->input('code')) {
return $this->response->errorBadRequest('验证码或邮箱错误!');
}
$user = auth('api')->user();
$user->email = $request->input('email');
$user->save();
return $this->response->noContent();
}
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();
}
}
我们 在发送短信使用到了事件以及队列,守护进程需要重启。重启命令:sudo supervisorctl restart all 。在发送短信上已经相当完善了。
在学习的php的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。
|