手机注册(1)验证码easy-sms

2019-06-13  本文已影响0人  Kent_Get

1、安装 easy-sms

composer require "overtrue/easy-sms"
image.png

安装成功。

2、配置
在config目录中增加easysms.php配置文件。config/easysms.php添加如下内容,这里我使用的阿里云的短信服务。

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

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

        // 默认可用的发送网关
        'gateways' => [
            'aliyun','yunpian',
        ],
    ],
    // 可用的网关配置
    'gateways' => [
        'errorlog' => [
            'file' => '/tmp/easy-sms.log',
        ],
        'aliyun' => [
            'access_key_id' => 'LTA*********6',//阿里云短信后台获取
            'access_key_secret' => 'VEm***********6kd',//阿里云短信后台获取
            'sign_name' => '',//签名名称,阿里云短信后台设置
        ],
    ],
];

3.为easy-sms增加一个服务提供者

php artisan make:provider EasySmsServiceProvider

添加内容如下

<?php

namespace App\Providers;

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

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

    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

在config/app.php注册服务提供者,在providers中增加

App\Providers\EasySmsServiceProvider::class,
  1. 修改users表,增加phone字段
php artisan make:migration add_phone_to_users_table --table=users

在新生成的迁移文件中找到 database/migrations/日期前缀_add_phone_to_users_table.php修改如下

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddPhoneToUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            //
            $table->string('phone')->nullable()->unique()->after('name');
            $table->string('email')->nullable()->change();//因为是手机注册,需要修改 email 字段为 nullable。
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            //
            $table->dropColumn('phone');
            $table->string('email')->nullable(false)->change();
        });
    }
}

执行php artisan migrate 时报错


image.png

提示修改字段属性需要安装doctrine/dbal。
安装doctrine/dbal组件

composer require doctrine/dbal
image.png

安装成功,重新执行

php artisan migrate
image.png

这次执行成功。

到此基础准备工作完成。

5.短信验证码接口
梳理下最简单的流程,如图所示


image.png

(1)构建api控制器基类
在app/Http/Controllers 目录下新建api目录,并在api目录中创建Controller.php文件。修改内容如下

<?php
namespace App\Http\Controllers\Api;

use Illuminate\Http\Request;
use Dingo\Api\Routing\Helpers;
use App\Http\Controllers\Controller as BaseController;

class Controller extends BaseController
{
    use Helpers;

}

api的基类中我们增加了 DingoApi 的 helper,这个 trait 可以帮助我们处理接口响应,后面 Api 控制器都会继承这个基础控制器。

(2)在 app/Http/Controllers/Api 中创建控制器VerificationCodesController,并修改代码如下

<?php

namespace App\Http\Controllers\Api;


class VerificationCodesController extends Controller
{
    public function store()
    {
        return $this->response->array(['info' => 'test info code']);
    }

}

我们利用 DingoApi 的 Helpers trait,使用 $this->response->array返回数据。
postman中进行测试

image.png
访问正常。

(3)为控制器创建表单请求验证类

php artisan make:request Api/VerificationCodeRequest

修改app/Http/Requests/Api/VerificationCodeRequest.php 内容如下

<?php

namespace App\Http\Requests\Api;

use Dingo\Api\Http\FormRequest;

class VerificationCodeRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'phone' => [
                'required',
                'regex:/^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199)\d{8}$/',
                'unique:users'
            ]
        ];
    }

}

(4)继续完成控制器
修改app/Http/Controllers/Api/VerificationCodesController.php代码如下

<?php

namespace App\Http\Controllers\Api;

use App\Http\Requests\Api\VerificationCodeRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Overtrue\EasySms\EasySms;

class VerificationCodesController extends Controller
{
    public function store(VerificationCodeRequest $request, EasySms $easySms)
    {
        $phone = $request->phone;

        // 生成4位随机数,左侧补0
        $code = str_pad(random_int(1, 9999), 4, 0, STR_PAD_LEFT);

        try {
            $result = $easySms->send($phone, [
                //'content'  =>  "尊敬的用户,您的注册会员动态密码为:{$code},请勿泄漏于他人!",
                'template' => 'SMS_********3',  //我使用的阿里云短信服务,这里是在阿里云后台设置的短信模板ID
                'data' => [
                    'code' => $code //阿里云短信后台模板中的短信验证码变量code,要对应
                ]

            ]);
        } catch (\Overtrue\EasySms\Exceptions\NoGatewayAvailableException $exception) {
            $message = $exception->getException('aliyun')->getMessage();
            return $this->response->errorInternal($message ?: '短信发送异常');
        }

        $key = 'verificationCode_'.str_random(15);
        $expiredAt = now()->addMinutes(10);
        // 缓存验证码 10分钟过期。
        Cache::put($key, ['phone' => $phone, 'code' => $code], $expiredAt);

        return $this->response->array([
            'key' => $key,
            'expired_at' => $expiredAt->toDateTimeString(),
        ])->setStatusCode(201);
    }

}

首先生成 4 位随机码,调用easySms 发送短信到用户手机,此处使用阿里云短信服务,不同短信平台需要传送参数格式不同。
发送成功后,生成一个 key,在缓存中存储这个 key 对应的手机以及验证码,10 分钟过期
将 key 以及 过期时间 返回给客户端,客户端根据获取到的key值请求下一接口。
处理顺序的接口时,常常是第一个接口返回一个随机的 key,利用这个 key 去调用第二个接口,这将为我们接下来要做的注册接口做准备。

关于发送成功后返回的随机 key 这里有几种思路:
使用手机号作为 key,不推荐这样,两个并发请求,如果使用了相同的手机号,无论是什么原因导致的这种情况的发生,都会造成某一个验证不通过;
为了防止上面一种情况,可以使用 手机号 + 几位随机字符串,例如 4 位随机字符串,或者当前时间戳,冲突的概率很小;
使用一个 x 位的随机字符串,一般短时间内的随机字符串,例如 15 位,冲突的概率也很小。

(5)测试接口
在postman中以post方式访问接口 http://你的域名/api/verificationCodes


image.png

成功返回了key,手机很快收到了短信验证码。
到此短信验证码准备成功,下面将进行手机注册接口的开发。

上一篇下一篇

猜你喜欢

热点阅读