abdullahfaqeir / laravel-otp
Requires
- php: ^8.2
- illuminate/database: ^9.0|^10.0|^11.0
- illuminate/notifications: ^9.0.2|^10.0|^11.0
- illuminate/support: ^9.0|^10.0|^11.0
Requires (Dev)
- mockery/mockery: ^1.4
- orchestra/testbench: ^7.0|^8.0
- php-coveralls/php-coveralls: ^2.1
- phpunit/phpunit: ^9.3
This package is auto-updated.
Last update: 2024-08-30 22:29:04 UTC
README
简介
大多数Web应用都需要一个OTP(一次性密码)或安全代码来验证用户。此包允许您使用用户友好的方法发送/重新发送并验证OTP以进行用户身份验证。
版本兼容性
基本用法
<?php /** * Send OTP via SMS. */ OTP()->send('+989389599530'); // or OTP('+989389599530'); /** * Send OTP via channels. */ OTP()->channel(['otp_sms', 'mail', \App\Channels\CustomSMSChannel::class]) ->send('+989389599530'); // or OTP('+989389599530', ['otp_sms', 'mail', \App\Channels\CustomSMSChannel::class]); /** * Send OTP for specific user provider */ OTP()->useProvider('admins') ->send('+989389599530'); /** * Validate OTP */ OTP()->validate('+989389599530', 'token_123'); // or OTP('+989389599530', 'token_123'); // or OTP()->useProvider('users') ->validate('+989389599530', 'token_123');
安装
您可以通过composer安装此包
composer require abdullahfaqeir/laravel-otp
配置
下一步,让我们通过执行以下命令发布配置文件 config/otp.php
php artisan vendor:publish --provider="AbdullahFaqeir\OTP\ServiceProvider" --tag="config"
令牌存储
此包允许您将生成的OTP存储在cache
或database
驱动器上,默认为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' => \AbdullahFaqeir\OTP\NotifiableRepository::class, ], // 'admins' => [ // 'model' => \App\Models\Admin::class, // 'repository' => \AbdullahFaqeir\OTP\NotifiableRepository::class, // ], ], //... ];
注意:您还可以更改默认存储库并替换您自己的存储库。但是,每个存储库都必须实现
AbdullahFaqeir\OTP\Contracts\NotifiableRepositoryInterface
接口。
模型准备
每个模型都必须实现AbdullahFaqeir\OTP\Contracts\OTPNotifiable
并使用此AbdullahFaqeir\OTP\Concerns\HasOTPNotify
特性
<?php namespace App\Models; use AbdullahFaqeir\OTP\Concerns\HasOTPNotify; use AbdullahFaqeir\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客户端
您可以使用任何SMS服务来发送OTP消息(这取决于您的选择)。
为了通过此包发送通知,首先您需要实现AbdullahFaqeir\OTP\Contracts\SMSClient
合同。此合同要求您实现sendMessage
方法。
此方法将通过包含用户mobile
和token
消息的AbdullahFaqeir\OTP\Notifications\Messages\MessagePayload
对象返回您的SMS服务API结果
<?php namespace App; use AbdullahFaqeir\OTP\Contracts\SMSClient; use AbdullahFaqeir\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
可以替换为您选择的SMS服务及其相应的方法。
接下来,您应该在配置文件中设置客户端包装类SampleSMSClient
// config/otp.php <?php return [ 'sms_client' => \App\SampleSMSClient::class, //... ];
实际示例
这里我们准备了一个实际示例。假设您将通过发送OTP来登录/注册客户
<?php namespace App\Http\Controllers; use App\Models\User; use AbdullahFaqeir\OTP\Exceptions\InvalidOTPTokenException; use AbdullahFaqeir\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' => \AbdullahFaqeir\OTP\Notifications\Channels\OTPSMSChannel::class, ];
注意:如果您更改了默认的短信通道,则
sms_client
将成为可选配置。否则,您必须定义自己的短信客户端。
通知短信和电子邮件定制
OTP通知默认准备了一个适用于大多数应用的短信和电子邮件格式。然而,您可以自定义邮件/短信消息的构建方式。
要开始,请向 AbdullahFaqeir\OTP\Notifications\OTPNotification
通知提供的 toSMSUsing/toMailUsing
方法传递一个闭包。闭包将接收接收通知的模型实例以及用于验证的 token
。通常,您应该从您的应用程序的 App\Providers\AuthServiceProvider
类的启动方法调用这些方法。
<?php use AbdullahFaqeir\OTP\Notifications\OTPNotification; use AbdullahFaqeir\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="AbdullahFaqeir\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
变更日志
有关最近更改的详细信息,请参阅 变更日志。
贡献
有关详细信息,请参阅 贡献指南。
安全
如果您发现任何安全问题,请发送电子邮件至 abdullahfaqeir.dev@gmail.com,而不是使用问题跟踪器。
许可
Laravel-OTP 在 MIT 许可下发布。有关详细信息,请参阅捆绑的 LICENSE 文件。
用 ❤️ 为您构建。