美文网首页
手机注册(1)验证码easy-sms

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

作者: Kent_Get | 来源:发表于2019-06-13 09:51 被阅读0次

    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,手机很快收到了短信验证码。
    到此短信验证码准备成功,下面将进行手机注册接口的开发。

    相关文章

      网友评论

          本文标题:手机注册(1)验证码easy-sms

          本文链接:https://www.haomeiwen.com/subject/kycrxctx.html