fouladgar/laravel-otp

此软件包提供方便的方法,用于向用户发送和验证OTP通知进行身份验证。

v4.3.0 2024-06-21 10:40 UTC

This package is auto-updated.

Last update: 2024-09-21 11:18:05 UTC


README

Latest Version on Packagist Test Status Code Style Status Total Downloads

简介

大多数Web应用都需要OTP(一次性密码)或安全码来验证用户。此软件包允许您使用用户友好的方法发送/重新发送并验证用户身份验证的OTP。

版本兼容性

基本用法

<?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');

安装

您可以通过Composer安装此软件包

composer require fouladgar/laravel-otp

配置

下一步,让我们通过执行以下命令发布配置文件 config/otp.php

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

令牌存储

该软件包允许您将生成的OTP存储在cachedatabase驱动程序上,默认为cache

您可以通过我们之前发布的配置文件更改首选驱动程序

// config/otp.php

<?php

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

请注意,Laravel OTP软件包使用已配置的cache驱动程序来存储令牌,如果您尚未配置或尚未计划配置,则可以使用database

数据库

这意味着迁移后,将创建一个表,您的应用程序需要在该表中存储验证令牌。

如果您使用的是其他列名(如mobile手机或otp_tokens表),则可以在配置文件中自定义其值

// config/otp.php

<?php

return [

    'mobile_column' => 'mobile',

    'token_table'   => 'otp_token',

    //...
];

根据token_storage配置,软件包将创建一个令牌表。此外,将向您的users默认提供者)表中添加一个mobile列,以显示用户验证状态并存储用户的手机号码。

好的!现在您应该迁移数据库

php artisan migrate

注意:当您使用OTP登录用户时,请考虑除了mobile列之外的所有列都必须可空。因为,在验证OTP后,如果用户不存在,则将创建用户记录。

用户提供者

您可能希望为不同类型的用户使用OTP。Laravel OTP允许您定义和管理您需要的多个用户提供者。为了设置,您应该打开config/otp.php文件并定义您的提供者

// 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,
       // ],
    ],

    //...
];

注意:您还可以更改默认存储库并替换您自己的存储库。但是,每个存储库都必须实现Fouladgar\OTP\Contracts\NotifiableRepositoryInterface接口。

模型准备

每个模型都必须实现Fouladgar\OTP\Contracts\OTPNotifiable,并使用此Fouladgar\OTP\Concerns\HasOTPNotify特性

<?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;

    // ...
}

短信客户端

您可以使用任何短信服务发送OTP消息(这取决于您的选择)。

为了通过此软件包发送通知,首先您需要实现Fouladgar\OTP\Contracts\SMSClient合同。此合同要求您实现sendMessage方法。

此方法将通过一个包含用户mobiletoken消息的Fouladgar\OTP\Notifications\Messages\MessagePayload对象返回您的短信服务API结果

<?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());
    }

    // ...
}

在上面的示例中,SMSService可以替换为您选择的短信服务及其相应的方法。

接下来,您应该在配置文件中设置客户端包装类SampleSMSClient

// config/otp.php

<?php

return [

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

  //...
];

实际示例

这里我们准备了一个实际示例。假设您将通过发送OTP来登录/注册客户

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Fouladgar\OTP\Exceptions\InvalidOTPTokenException;
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 (InvalidOTPTokenException $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.']);
    }
}

定制

通知默认通道定制

对于发送OTP通知,有一个默认通道。但是,此软件包允许您使用自己的通知通道。为了替换,您应在此处指定通道类

//config/otp.php
<?php
return [
    // ...

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

注意:如果您更改默认短信通道,则sms_client将是一个可选配置。否则,您必须定义您的短信客户端。

通知短信和电子邮件自定义

OTP通知准备了一个默认短信和电子邮件格式,这些格式适用于大多数应用程序。但是,您可以自定义邮件/短信消息的构建方式。

要开始,请将闭包传递给由Fouladgar\OTP\Notifications\OTPNotification通知提供的toSMSUsing/toMailUsing方法。闭包将接收到接收通知的通知模型实例以及用于验证的token。通常,您应该从您的应用程序的App\Providers\AuthServiceProvider类的boot方法中调用这些方法

<?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));

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

翻译

要发布翻译文件,您可以使用此命令

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

您可以在提供的语言文件中进行自定义

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

<?php

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

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

测试

composer test

变更日志

有关最近更改的更多信息,请参阅变更日志

贡献

有关详细信息,请参阅贡献指南

安全

如果您发现任何与安全相关的问题,请通过电子邮件fouladgar.dev@gmail.com联系,而不是使用问题跟踪器。

许可证

Laravel-OTP是在MIT许可证下发布的。有关详细信息,请参阅捆绑的LICENSE文件。

用❤️为您构建。