metasoftdevs/laravel-breeze-2fa

Advanced two-factor authentication package for Laravel Breeze with multi-channel support (TOTP, Email, SMS) and custom authentication integration

dev-main 2025-07-26 20:32 UTC

This package is not auto-updated.

Last update: 2025-07-27 17:31:48 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

An advanced, highly customizable two-factor authentication (2FA) package for Laravel Breeze that supports multiple authentication methods and seamlessly integrates with both Breeze and custom authentication systems.

โœจ Features

  • ๐Ÿ” Multiple 2FA Methods: TOTP (Authenticator Apps), Email OTP, SMS OTP
  • ๐Ÿ”‘ Recovery Codes: Secure backup codes for account recovery
  • ๐Ÿ“ฑ Device Remembering: Optional "trust this device" functionality
  • ๐Ÿ›ก๏ธ Security First: Rate limiting, encryption, CSRF protection
  • ๐ŸŽจ Laravel Breeze Integration: Drop-in compatibility with Breeze
  • ๐Ÿ”ง Highly Customizable: Extensive configuration options
  • ๐Ÿ“‹ Custom Auth Support: Works with any Laravel authentication guard
  • ๐Ÿงช Fully Tested: Comprehensive test suite with 90%+ coverage
  • ๐Ÿ“š Well Documented: Extensive documentation and examples

๐Ÿ“‹ Requirements

  • PHP 8.1 or higher
  • Laravel 10.0 or higher
  • Laravel Breeze (for seamless integration)

๐Ÿš€ Quick Start

Installation

Install the package via Composer:

composer require metasoftdevs/laravel-breeze-2fa

Basic Setup

  1. Publish and run migrations:
php artisan vendor:publish --provider="MetaSoftDevs\LaravelBreeze2FA\TwoFactorServiceProvider" --tag="two-factor-migrations"
php artisan migrate
  1. Publish configuration (optional):
php artisan vendor:publish --provider="MetaSoftDevs\LaravelBreeze2FA\TwoFactorServiceProvider" --tag="two-factor-config"
  1. Install the package setup:
php artisan two-factor:install

Laravel Breeze Integration

If you're using Laravel Breeze, the package will automatically integrate with your existing authentication flow:

// In your login controller or middleware
use MetaSoftDevs\LaravelBreeze2FA\Facades\TwoFactor;

// After successful password authentication
if (TwoFactor::isEnabledForUser($user)) {
    if (!TwoFactor::isDeviceRemembered($user)) {
        // Redirect to 2FA challenge
        return redirect()->route('two-factor.challenge');
    }
}

๐Ÿ“– Usage Examples

Enabling 2FA for a User

use MetaSoftDevs\LaravelBreeze2FA\Facades\TwoFactor;

// Enable TOTP (Authenticator App)
$setup = TwoFactor::enable($user, 'totp');
$qrCodeUrl = $setup['qr_code_url'];
$secret = $setup['secret'];
$recoveryCodes = $setup['recovery_codes'];

// Enable Email OTP
$setup = TwoFactor::enable($user, 'email');
// A verification email will be sent automatically

// Enable SMS OTP
$setup = TwoFactor::enable($user, 'sms');
// A verification SMS will be sent automatically

Confirming 2FA Setup

// User enters the code from their authenticator app/email/SMS
$isConfirmed = TwoFactor::confirm($user, $userProvidedCode);

if ($isConfirmed) {
    // 2FA is now active for the user
    return redirect()->route('dashboard')->with('success', '2FA enabled successfully!');
}

Verifying 2FA During Login

// In your authentication flow
try {
    $verified = TwoFactor::verify($user, $code, $rememberDevice = true);

    if ($verified) {
        // User is authenticated, proceed with login
        Auth::login($user);
        return redirect()->intended('dashboard');
    }
} catch (\MetaSoftDevs\LaravelBreeze2FA\Exceptions\InvalidCodeException $e) {
    return back()->withErrors(['code' => 'Invalid verification code']);
} catch (\MetaSoftDevs\LaravelBreeze2FA\Exceptions\RateLimitExceededException $e) {
    return back()->withErrors(['code' => 'Too many attempts. Please try again later.']);
}

Disabling 2FA

$disabled = TwoFactor::disable($user);

if ($disabled) {
    return redirect()->back()->with('success', '2FA has been disabled.');
}

Getting User's 2FA Status

$status = TwoFactor::getStatus($user);

/*
Returns:
[
    'enabled' => true,
    'method' => 'totp',
    'confirmed' => true,
    'recovery_codes_count' => 6,
    'can_generate_recovery_codes' => true
]
*/

๐Ÿ”ง Configuration

The package offers extensive configuration options. Publish the config file to customize:

php artisan vendor:publish --provider="MetaSoftDevs\LaravelBreeze2FA\TwoFactorServiceProvider" --tag="two-factor-config"

Key Configuration Options

// config/two-factor.php

return [
    // Enable/disable the entire 2FA system
    'enabled' => env('TWO_FACTOR_ENABLED', true),

    // Require all users to set up 2FA
    'required' => env('TWO_FACTOR_REQUIRED', false),

    // Configure available methods
    'methods' => [
        'totp' => [
            'enabled' => true,
            'issuer' => env('APP_NAME'),
            'window' => 1, // Time drift tolerance
        ],
        'email' => [
            'enabled' => true,
            'expiry' => 300, // 5 minutes
        ],
        'sms' => [
            'enabled' => false,
            'provider' => 'twilio',
        ],
    ],

    // Recovery codes settings
    'recovery_codes' => [
        'enabled' => true,
        'count' => 8,
        'length' => 10,
    ],

    // Device remembering
    'remember_device' => [
        'enabled' => true,
        'duration' => 30 * 24 * 60, // 30 days
    ],

    // Rate limiting
    'rate_limiting' => [
        'max_attempts' => 5,
        'decay_minutes' => 15,
    ],
];

๐Ÿ”’ SMS Configuration

For SMS OTP, configure your provider credentials:

Twilio

TWILIO_ACCOUNT_SID=your_account_sid
TWILIO_AUTH_TOKEN=your_auth_token
TWILIO_PHONE_NUMBER=your_twilio_number

Vonage (Nexmo)

VONAGE_API_KEY=your_api_key
VONAGE_API_SECRET=your_api_secret
VONAGE_PHONE_NUMBER=your_sender_id

๐ŸŽจ Frontend Integration

Blade Templates

The package includes pre-built Blade templates that you can customize:

php artisan vendor:publish --provider="MetaSoftDevs\LaravelBreeze2FA\TwoFactorServiceProvider" --tag="two-factor-views"

Vue.js/Inertia.js

For Vue.js applications using Inertia:

// Setup 2FA
const setup2FA = async (method) => {
  const response = await axios.post("/two-factor/enable", { method });

  if (method === "totp") {
    // Show QR code: response.data.qr_code_url
    showQRCode(response.data.qr_code_url);
  }

  // Show recovery codes
  showRecoveryCodes(response.data.recovery_codes);
};

// Verify setup
const confirm2FA = async (code) => {
  await axios.post("/two-factor/confirm", { code });
  // 2FA is now enabled
};

Livewire

For Livewire components:

class TwoFactorSetup extends Component
{
    public $method = 'totp';
    public $code = '';
    public $qrCodeUrl = '';
    public $recoveryCodes = [];

    public function enable()
    {
        $setup = TwoFactor::enable(auth()->user(), $this->method);
        $this->qrCodeUrl = $setup['qr_code_url'] ?? '';
        $this->recoveryCodes = $setup['recovery_codes'] ?? [];
    }

    public function confirm()
    {
        TwoFactor::confirm(auth()->user(), $this->code);
        session()->flash('message', '2FA enabled successfully!');
    }
}

๐Ÿ› ๏ธ Custom Authentication Integration

For custom authentication systems, implement the 2FA flow manually:

use MetaSoftDevs\LaravelBreeze2FA\Facades\TwoFactor;

// In your custom login controller
class CustomLoginController extends Controller
{
    public function authenticate(Request $request)
    {
        // Your existing authentication logic
        $user = $this->attemptLogin($request);

        if ($user && TwoFactor::isEnabledForUser($user)) {
            if (!TwoFactor::isDeviceRemembered($user)) {
                // Store user in session for 2FA challenge
                session(['2fa_user_id' => $user->id]);
                return redirect()->route('two-factor.challenge');
            }
        }

        // Complete login
        Auth::login($user);
        return redirect()->intended();
    }

    public function challenge()
    {
        // Show 2FA challenge form
        return view('auth.two-factor-challenge');
    }

    public function verify(Request $request)
    {
        $userId = session('2fa_user_id');
        $user = User::find($userId);

        $verified = TwoFactor::verify($user, $request->code, $request->boolean('remember'));

        if ($verified) {
            session()->forget('2fa_user_id');
            Auth::login($user);
            return redirect()->intended();
        }

        return back()->withErrors(['code' => 'Invalid code']);
    }
}

๐Ÿงช Testing

Run the package tests:

composer test

Run tests with coverage:

composer test-coverage

๐Ÿ“‹ Commands

The package includes several Artisan commands:

# Install the package (publish assets, run migrations)
php artisan two-factor:install

# Generate recovery codes for a user
php artisan two-factor:recovery-codes {user-id}

# Clean up expired sessions and codes
php artisan two-factor:cleanup

# Show 2FA statistics
php artisan two-factor:stats

๐Ÿ” Security Considerations

  • Secrets Encryption: TOTP secrets are encrypted in the database
  • Rate Limiting: Prevents brute force attacks on 2FA codes
  • Recovery Codes: Securely hashed and single-use
  • Device Tokens: Cryptographically secure device remembering
  • Audit Trail: All authentication attempts are logged
  • CSRF Protection: All forms include CSRF tokens

๐Ÿค Contributing

We welcome contributions! Please see CONTRIBUTING.md for details.

Development Setup

  1. Clone the repository
  2. Install dependencies: composer install
  3. Run tests: composer test
  4. Check code style: composer format

๐Ÿ“œ Changelog

Please see CHANGELOG.md for more information on what has changed recently.

๐Ÿ›ก๏ธ Security

If you discover any security-related issues, please email security@metasoft.dev instead of using the issue tracker.

๐Ÿ“„ License

The MIT License (MIT). Please see License File for more information.

๐Ÿ™ Credits

๐Ÿ”— Related Packages

Built with โค๏ธ by Meta Software Developers
info@metasoftdevs.com