Two-Factor Authentication package for Laravel that supports:
- Google Authenticator (TOTP)
- Self-generated one-time codes with configurable expiry
- Delivery via Email (built-in), SMS, or WhatsApp (user-provided callbacks)
- Built-in fraud protection: attempt limits, cooldowns, per-user lock
- PHP 8.1+
- Laravel 10 or 11
composer require elgibor-solution/laravel-2fa
Publish config and (optionally) migrations:
php artisan vendor:publish --provider="ESolution\Laravel2FA\Laravel2FAServiceProvider" --tag=2fa-config
php artisan vendor:publish --provider="ESolution\Laravel2FA\Laravel2FAServiceProvider" --tag=2fa-migrations
php artisan migrate
config/2fa.php
channels.email/sms/whatsapp
— enable built-in email sender; provide SMS/WhatsApp callbacks.self_generated_ttl
— expiry (seconds) for self-generated codes.code_length
— digits for self-generated codes.max_attempts
,lock_minutes_after_max
— fraud control.cooldown_seconds_between_requests
— min time between code requests.totp_drift
— allowed time drift for TOTP.issuer
— shown in Google Authenticator.tables
— override table names if needed.
In AppServiceProvider@boot()
or any service provider:
use Illuminate\Support\Facades\App;
// SMS
App::singleton('2fa.sender.sms', function () {
return function (string $to, string $message, array $context = []) {
// Integrate your SMS gateway here
// Example: Sms::to($to)->send($message);
};
});
// WhatsApp
App::singleton('2fa.sender.whatsapp', function () {
return function (string $to, string $message, array $context = []) {
// Integrate your WhatsApp provider here
// Example: WhatsApp::sendText($to, $message);
};
});
Email is supported out of the box via Mail::raw()
.
These routes are auto-registered under /2fa
with web,auth
middleware.
POST /2fa/init-totp
→ Start TOTP setup. Returns{ secret, otpauth_uri }
.POST /2fa/confirm-totp
→ Enable TOTP (body:code
).POST /2fa/disable
→ Disable 2FA for the authenticated user.POST /2fa/create
→ Generate self code and send (body:channel, destination, purpose?
).POST /2fa/validate
→ Validate any code (body:code, purpose?
).
use TwoFA;
// Start TOTP enrollment
$resp = TwoFA::initTotp($user->id); // ['secret' => '...', 'otpauth_uri' => '...']
// Confirm and enable TOTP
$ok = TwoFA::confirmTotp($user->id, $request->code);
// Disable 2FA
TwoFA::disable($user->id);
// Create a self-generated code and deliver it
$res = TwoFA::createSelfGenerated($user->id, 'sms', $user->phone, 'login');
// Validate a code (works for TOTP or self-generated depending on user settings)
$isValid = TwoFA::validate($user->id, $request->code, 'login');
initTotp()
returns an otpauth://
URI. Render a QR code on your frontend using any QR library (e.g., JavaScript QR libraries). Users can scan that QR with Google Authenticator.
- Hashed codes at rest (HMAC-SHA256 with
APP_KEY
). Sethash_codes=false
to store plaintext (not recommended). - Per-code attempt limit (config
max_attempts
). - Cooldown between requests (
cooldown_seconds_between_requests
). - Temporary account lock after too many failures (
lock_minutes_after_max
). Lock status is tracked intwo_fa_settings.locked_until
. - IP & User-Agent logging for every action in
two_fa_logs
.
Tip: Add additional monitoring or alerts by listening to model events or querying
two_fa_logs
.
An optional middleware ESolution\Laravel2FA\Http\Middleware\Enforce2FA
is included. It blocks requests if the account is currently locked. Register it in app/Http/Kernel.php
and apply where needed.
protected $routeMiddleware = [
// ...
'enforce2fa' => \ESolution\Laravel2FA\Http\Middleware\Enforce2FA::class,
];
two_fa_settings
: per-user status, method (totp
orself
), secret, lock.two_fa_codes
: self-generated codes, expiry, attempts, delivery channel.two_fa_logs
: audit log of events.
- Enable mail logging (e.g.,
MAIL_MAILER=log
) to see email messages in logs. - For SMS/WhatsApp, just bind callbacks that
Log::info()
the outbound text.
Need professional help or want to move faster? Hire the E-Solution / Elgibor team for integration, audits, or custom features.
📧 [email protected]
If this package saves you time, consider supporting development ❤️
Apache-2.0