benbjurstrom/otpz
Composer 安装命令:
composer require benbjurstrom/otpz
包简介
First Factor One-Time Passwords for Laravel (Passwordless OTP Login)
关键字:
README 文档
README
First Factor One-Time Passwords for Laravel
This package provides secure first factor one-time passwords (OTPs) for Laravel applications. Users enter their email and receive a one-time code to sign in—no passwords required.
Features
- ✅ Session-locked - OTPs only work in the browser session that requested them
- ✅ Rate-limited - Configurable throttling with multi-tier limits
- ✅ Time-based expiration - Default 5 minutes, fully configurable
- ✅ Invalidated after first use - One-time use only
- ✅ Attempt limiting - Invalidated after 3 failed attempts
- ✅ Signed URLs - Cryptographic signature validation
- ✅ Detailed error messages - Clear feedback for users
- ✅ Customizable templates - Bring your own email design
- ✅ Auditable - Full event logging via Laravel events
Quick Start
Prerequisites
OTPz works best with the official Laravel starter kits:
- React (Inertia.js)
- Vue (Inertia.js)
- Livewire (Volt)
OTPz's frontend components are designed to work out of the box with the Laravel starter kits and make use of their existing UI components (Button, Input, Label, etc.). Because these components are installed into your application you are free to customize them for any Laravel application using React, Vue, or Livewire.
Installation
1. Install the Package
composer require benbjurstrom/otpz
2. Run Migrations
php artisan vendor:publish --tag="otpz-migrations"
php artisan migrate
3. Add Interface and Trait to User Model
// app/Models/User.php namespace App\Models; use BenBjurstrom\Otpz\Models\Concerns\HasOtps; use BenBjurstrom\Otpz\Models\Concerns\Otpable; // ... class User extends Authenticatable implements Otpable { use HasFactory, Notifiable, HasOtps; // ... }
Framework-Specific Setup
Choose your frontend framework:
React (Inertia.js)
1. Publish Components
php artisan vendor:publish --tag="otpz-react"
This copies the following files to your application:
resources/js/pages/auth/otpz-login.tsx- Email entry pageresources/js/pages/auth/otpz-verify.tsx- OTP code entry pageapp/Http/Controllers/Auth/OtpzController.php- Self-contained controller handling all OTP logic
Note: These components import shadcn/ui components (
Button,Input,Label,Checkbox), layout components (AuthLayout), and use wayfinder for route generation from the Laravel React starter kit. If you're not using the starter kit, you may need to adjust these imports or create these components.
2. Add Routes
Add to routes/web.php:
use App\Http\Controllers\Auth\OtpzController; Route::middleware('guest')->group(function () { Route::get('otpz', [OtpzController::class, 'index']) ->name('otpz.index'); Route::post('otpz', [OtpzController::class, 'store']) ->name('otpz.store'); Route::get('otpz/{id}', [OtpzController::class, 'show']) ->name('otpz.show') ->middleware('signed'); Route::post('otpz/{id}', [OtpzController::class, 'verify']) ->name('otpz.verify') ->middleware('signed'); });
That's it! The controller handles all the OTP logic for you.
Vue (Inertia.js)
1. Publish Components
php artisan vendor:publish --tag="otpz-vue"
This copies the following files to your application:
resources/js/pages/auth/OtpzLogin.vue- Email entry pageresources/js/pages/auth/OtpzVerify.vue- OTP code entry pageapp/Http/Controllers/Auth/OtpzController.php- Self-contained controller handling all OTP logic
Note: These components import layout components (
AuthLayout), and use wayfinder for route generation from the Laravel Vue starter kit. If you're not using the starter kit, you may need to adjust these imports or create these components.
2. Add Routes
Add to routes/web.php:
use App\Http\Controllers\Auth\OtpzController; Route::middleware('guest')->group(function () { Route::get('otpz', [OtpzController::class, 'index']) ->name('otpz.index'); Route::post('otpz', [OtpzController::class, 'store']) ->name('otpz.store'); Route::get('otpz/{id}', [OtpzController::class, 'show']) ->name('otpz.show') ->middleware('signed'); Route::post('otpz/{id}', [OtpzController::class, 'verify']) ->name('otpz.verify') ->middleware('signed'); });
That's it! The controller handles all the OTP logic for you.
Livewire (Volt)
1. Publish Components
php artisan vendor:publish --tag="otpz-livewire"
This copies the following files to your application:
resources/views/livewire/auth/otpz-login.blade.php- Email entry pageresources/views/livewire/auth/otpz-verify.blade.php- OTP code entry pageapp/Http/Controllers/Auth/PostOtpController.php- Self-contained controller handling OTP verification
Note: These Volt components use Flux UI components and layout components from the Laravel Livewire starter kit. If you're not using the starter kit, you may need to adjust the component markup and styling.
2. Add Routes
Add to routes/web.php:
use App\Http\Controllers\Auth\PostOtpController; use Livewire\Volt\Volt; Route::middleware('guest')->group(function () { Volt::route('otpz', 'auth.otpz-login') ->name('otpz.index'); Volt::route('otpz/{id}', 'auth.otpz-verify') ->middleware('signed') ->name('otpz.show'); Route::post('otpz/{id}', PostOtpController::class) ->middleware('signed') ->name('otpz.verify'); });
Replacing Fortify Login (Optional)
The latest Laravel starter kits use Laravel Fortify for authentication. If you want to replace the default username/password login with OTPz:
For React:
In app/Providers/FortifyServiceProvider.php, update the loginView method:
Fortify::loginView(fn (Request $request) => Inertia::render('auth/otpz-login', []));
For Vue:
In app/Providers/FortifyServiceProvider.php, update the loginView method:
Fortify::loginView(fn (Request $request) => Inertia::render('auth/OtpzLogin', []));
For Livewire:
In app/Providers/FortifyServiceProvider.php, comment out the default login view:
// Fortify::loginView(fn () => view('livewire.auth.login'));
Then in routes/web.php, update the OTPz route to use login:
Volt::route('login', 'auth.otpz-login') ->name('login'); // Changed path and name from 'otpz'
Now when users visit /login or are redirected to the login page, they'll see the OTPz email entry form instead of the traditional username/password form.
Configuration
Publish Configuration File (Optional)
php artisan vendor:publish --tag="otpz-config"
This is the contents of the published config file:
<?php return [ /* |-------------------------------------------------------------------------- | Expiration and Throttling |-------------------------------------------------------------------------- | | These settings control the security aspects of the generated codes, | including their expiration time and the throttling mechanism to prevent | abuse. | */ 'expiration' => 5, // Minutes 'limits' => [ ['limit' => 1, 'minutes' => 1], ['limit' => 3, 'minutes' => 5], ['limit' => 5, 'minutes' => 30], ], /* |-------------------------------------------------------------------------- | Model Configuration |-------------------------------------------------------------------------- | | This setting determines the model used by Otpz to store and retrieve | one-time passwords. By default, it uses the 'App\Models\User' model. | */ 'models' => [ 'authenticatable' => App\Models\User::class, ], /* |-------------------------------------------------------------------------- | Mailable Configuration |-------------------------------------------------------------------------- | | This setting determines the Mailable class used by Otpz to send emails. | Change this to your own Mailable class if you want to customize the email | sending behavior. | */ 'mailable' => BenBjurstrom\Otpz\Mail\OtpzMail::class, /* |-------------------------------------------------------------------------- | Template Configuration |-------------------------------------------------------------------------- | | This setting determines the email template used by Otpz to send emails. | Switch to 'otpz::mail.notification' if you prefer to use the default | Laravel notification template. | */ 'template' => 'otpz::mail.otpz', // 'template' => 'otpz::mail.notification', /* |-------------------------------------------------------------------------- | User Resolver |-------------------------------------------------------------------------- | | Defines the class responsible for finding or creating users by email address. | The default implementation will create a new user when an email doesn't exist. | Replace with your own implementation for custom user resolution logic. | */ 'user_resolver' => BenBjurstrom\Otpz\Actions\GetUserFromEmail::class, ];
7. (Optional) Publish the translations file
php artisan vendor:publish --tag="otpz-translations"
This package publishes the translations file:
lang/
└── vendor/
└── en
└── otp.php (standart translations)
Customization
Email Templates
Publish the email templates to customize styling:
php artisan vendor:publish --tag="otpz-views"
This publishes:
resources/views/vendor/otpz/
├── mail/
│ ├── otpz.blade.php # Custom styled template
│ └── notification.blade.php # Laravel notification template
└── components/
└── template.blade.php
Switch between templates in config/otpz.php:
'template' => 'otpz::mail.notification', // Use Laravel's default styling
Custom User Resolution
By default, OTPz creates new users when an email doesn't exist. You can customize this behavior by creating your own user resolver and registering it in the config. In this example we throw a validation error if a user with the given email address does not exist.
namespace App\Actions; use App\Models\User; use BenBjurstrom\Otpz\Models\Concerns\Otpable; use Illuminate\Validation\ValidationException; class MyUserResolver { public function handle(string $email): Otpable { $user = User::where('email', $email)->first(); if($user){ return $user; } throw ValidationException::withMessages([ 'email' => 'No user found with that email address.', ]); } }
Update config/otpz.php:
'user_resolver' => App\Actions\MyUserResolver::class,
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.
benbjurstrom/otpz 适用场景与选型建议
benbjurstrom/otpz 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 11.69k 次下载、GitHub Stars 达 282, 最近一次更新时间为 2024 年 12 月 10 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「laravel」 「Ben Bjurstrom」 「otpz」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 benbjurstrom/otpz 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 benbjurstrom/otpz 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 benbjurstrom/otpz 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
OpemAmAuth is a client for authenticating against OpenAM in PHP
Pgvector driver for Laravel Scout
LdapLookup is a tool to lookup entries in LDAP For Laravel 5.1+
First Factor One-Time Passwords for Laravel (Passwordless OTP Login)
Alfabank REST API integration
Authorize.net payment gateway plugin for Sylius applications.
统计信息
- 总下载量: 11.69k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 282
- 点击次数: 40
- 依赖项目数: 2
- 推荐数: 1
其他信息
- 授权协议: MIT
- 更新时间: 2024-12-10