fouladgar/laravel-otp 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

fouladgar/laravel-otp

Composer 安装命令:

composer require fouladgar/laravel-otp

包简介

This package provides convenient methods for sending and validating OTP notifications to users for authentication.

README 文档

README

Latest Version on Packagist Test Status Code Style Status Total Downloads

Introduction

Most web applications need an OTP(one-time password) or secure code to validate their users. This package allows you to send/resend and validate OTP for users authentication with user-friendly methods.

Basic Usage:

<?php

/*
|--------------------------------------------------------------------------
| Send OTP via SMS.
|--------------------------------------------------------------------------
*/
OTP()->send('+98900000000'); 
// Or
OTP('+98900000000');

/*
|--------------------------------------------------------------------------
| Send OTP via channels.
|--------------------------------------------------------------------------
*/
OTP()->channel(['otp_sms', 'mail', \App\Channels\CustomSMSChannel::class])
     ->send('+98900000000');
// Or
OTP('+98900000000', ['otp_sms', 'mail', \App\Channels\CustomSMSChannel::class]);

/*
|--------------------------------------------------------------------------
| Send OTP for specific user provider
|--------------------------------------------------------------------------
*/
OTP()->useProvider('admins')
     ->send('+98900000000');
 
/*
|--------------------------------------------------------------------------
|  Validate OTP
|--------------------------------------------------------------------------
*/
OTP()->validate('+98900000000', 'token_123');
// Or
OTP('+98900000000', 'token_123');

/*
|--------------------------------------------------------------------------
| Validate OTP for specific user provider
|--------------------------------------------------------------------------
*/
OTP()->useProvider('users')
     ->validate('+98900000000', 'token_123');
/*
|--------------------------------------------------------------------------
| You may wish to only confirm the token
|--------------------------------------------------------------------------
*/
OTP()->onlyConfirmToken()   
     ->validate('+98900000000', 'token_123');

/*
|--------------------------------------------------------------------------
| You may wish to use a custom indicator
|--------------------------------------------------------------------------
*/
OTP()->indicator('custom_indicator')   
     ->send('+98900000000');
     
OTP()->indicator('custom_indicator')
     ->onlyConfirmToken() 
     ->validate('+98900000000', 'token_123');

Installation

You can install the package via composer:

composer require fouladgar/laravel-otp

Configuration

As next step, let's publish config file config/otp.php by executing:

php artisan vendor:publish --provider="Fouladgar\OTP\ServiceProvider" --tag="config"

Token Storage

Package allows you to store the generated one-time password on either cache or database driver, default is cache.

You can change the preferred driver through config file that we published earlier:

// config/otp.php

<?php

return [
    /**
    |Supported drivers: "cache", "database"
    */
    'token_storage' => 'cache',
];
Cache

Note that Laravel OTP package uses the already configured cache driver to storage token, if you have not configured one yet or have not planned to do it you can use database instead.

Database

It means after migrating, a table will be created which your application needs to store verification tokens.

If you’re using another column name for mobile phone or even otp_tokens table, you can customize their values in config file:

// config/otp.php

<?php

return [

    'mobile_column' => 'mobile',

    'token_table'   => 'otp_token',

    //...
];

Depending on the token_storage config, the package will create a token table. Also, a mobile column will be added to your users (default provider) table to show user verification state and store user's mobile phone.

All right! Now you should migrate the database:

php artisan migrate

Note: When you are using OTP to login user, consider all columns must be nullable except for the mobile column. Because, after verifying OTP, a user record will be created if the user does not exist.

Token Life Time

You can specify an OTP token_lifetime, ensuring that once an OTP token is sent to the user, no new OTP token will be generated or sent until the current token has expired.

// config/otp.php

<?php

return [
    //...

        'token_lifetime' => env('OTP_TOKEN_LIFE_TIME', 5),
    ],

    //...
];

User providers

You may wish to use the OTP for variant users. Laravel OTP allows you to define and manage many user providers that you need. In order to set up, you should open config/otp.php file and define your providers:

// config/otp.php

<?php

return [
    //...

    'default_provider' => 'users',

    'user_providers'  => [
        'users' => [
            'table'      => 'users',
            'model'      => \App\Models\User::class,
            'repository' => \Fouladgar\OTP\NotifiableRepository::class,
        ],

       // 'admins' => [
       //   'model'      => \App\Models\Admin::class,
       //   'repository' => \Fouladgar\OTP\NotifiableRepository::class,
       // ],
    ],

    //...
];

Note: You may also change the default repository and replace your own repository. however, every repository must implement Fouladgar\OTP\Contracts\NotifiableRepositoryInterface interface.

Model Preparation

Every model must implement Fouladgar\OTP\Contracts\OTPNotifiable and also use this Fouladgar\OTP\Concerns\HasOTPNotify trait:

<?php

namespace App\Models;

use Fouladgar\OTP\Concerns\HasOTPNotify;
use Fouladgar\OTP\Contracts\OTPNotifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable implements OTPNotifiable
{
    use Notifiable;
    use HasOTPNotify;

    // ...
}

SMS Client

You can use any SMS services for sending OTP message(it depends on your choice).

For sending notifications via this package, first you need to implement the Fouladgar\OTP\Contracts\SMSClient contract. This contract requires you to implement sendMessage method.

This method will return your SMS service API results via a Fouladgar\OTP\Notifications\Messages\MessagePayload object which contains user mobile and token message:

<?php

namespace App;

use Fouladgar\OTP\Contracts\SMSClient;
use Fouladgar\OTP\Notifications\Messages\MessagePayload;

class SampleSMSClient implements SMSClient
{
    public function __construct(protected SampleSMSService $SMSService)
    {
    }

    public function sendMessage(MessagePayload $payload): mixed
    {
        return $this->SMSService->send($payload->to(), $payload->content());
    }

    // ...
}

In above example, SMSService can be replaced with your chosen SMS service along with its respective method.

Next, you should set the client wrapper SampleSMSClient class in config file:

// config/otp.php

<?php

return [

  'sms_client' => \App\SampleSMSClient::class,

  //...
];

Practical Example

Here we have prepared a practical example. Suppose you are going to login/register a user by sending an OTP:

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Fouladgar\OTP\Exceptions\OTPException;
use Fouladgar\OTP\OTPBroker as OTPService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Throwable;

class AuthController
{
    public function __construct(private OTPService $OTPService)
    {
    }

    public function sendOTP(Request $request): JsonResponse
    {
        try {
            /** @var User $user */
            $user = $this->OTPService->send($request->get('mobile'));
        } catch (Throwable $ex) {
          // or prepare and return a view.
           return response()->json(['message' => 'An unexpected error occurred.'], 500);
        }

        return response()->json(['message' => 'A token has been sent to:'. $user->mobile]);
    }

    public function verifyOTPAndLogin(Request $request): JsonResponse
    {
        try {
            /** @var User $user */
            $user = $this->OTPService->validate($request->get('mobile'), $request->get('token'));

            // and do login actions...

        } catch (OTPException $exception){
             return response()->json(['error' => $exception->getMessage()],$exception->getCode());
        } catch (Throwable $ex) {
            return response()->json(['message' => 'An unexpected error occurred.'], 500);
        }

         return response()->json(['message' => 'Logged in successfully.']);
    }
}

Customization

Notification Default Channel Customization

For sending OTP notification there is a default channel. But this package allows you to use your own notification channel. In order to replace, you should specify channel class here:

//config/otp.php
<?php

return [
    // ...

    'channel' => \Fouladgar\OTP\Notifications\Channels\OTPSMSChannel::class,
];

Note: If you change the default sms channel, the sms_client will be an optional config. Otherwise, you must define your sms client.

Notification SMS and Email Customization

OTP notification prepares a default sms and email format that are satisfied for most application. However, you can customize how the mail/sms message is constructed.

To get started, pass a closure to the toSMSUsing/toMailUsing method provided by the Fouladgar\OTP\Notifications\OTPNotification notification. The closure will receive the notifiable model instance that is receiving the notification as well as the token for validating. Typically, you should call the those methods from the boot method of your application's App\Providers\AuthServiceProvider class:

<?php

use Fouladgar\OTP\Notifications\OTPNotification;
use Fouladgar\OTP\Notifications\Messages\OTPMessage;
use Illuminate\Notifications\Messages\MailMessage;

public function boot()
{
    // ...

    // SMS Customization
    OTPNotification::toSMSUsing(fn($notifiable, $token) =>(new OTPMessage())
                    ->to($notifiable->mobile)
                    ->content('Your OTP Token is: '.$token))
                    ->template('OTP_TEMPLATE');

    //Email Customization
    OTPNotification::toMailUsing(fn ($notifiable, $token) =>(new MailMessage)
            ->subject('OTP Request')
            ->line('Your OTP Token is: '.$token));
}

Translates

To publish translation file you may use this command:

php artisan vendor:publish --provider="Fouladgar\OTP\ServiceProvider" --tag="lang"

you can customize in provided language file:

// resources/lang/vendor/OTP/en/otp.php

<?php

return [
    'otp_token' => 'Your OTP Token is: :token.',

    'otp_subject' => 'OTP request',
];

Testing

composer test

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email fouladgar.dev@gmail.com instead of using the issue tracker.

License

Laravel-OTP is released under the MIT License. See the bundled LICENSE file for details.

Built with ❤️ for you.

fouladgar/laravel-otp 适用场景与选型建议

fouladgar/laravel-otp 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 27.58k 次下载、GitHub Stars 达 212, 最近一次更新时间为 2022 年 01 月 21 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「laravel」 「otp」 「one-time-password」 「lumen」 「laravel-otp」 「otp-login」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 fouladgar/laravel-otp 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 fouladgar/laravel-otp 我们能提供哪些服务?
定制开发 / 二次开发

基于 fouladgar/laravel-otp 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 27.58k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 212
  • 点击次数: 19
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 212
  • Watchers: 3
  • Forks: 37
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2022-01-21