Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon How do I integrate Google Authenticator with Laravel Fortify for two-factor authentication


How do I integrate Google Authenticator with Laravel Fortify for two-factor authentication


Integrating Google Authenticator with Laravel Fortify for two-factor authentication involves several key steps including package installation, configuration, user interface creation, and flow management to ensure the security and usability of two-factor authentication (2FA). Below is a thorough step-by-step guide detailing each aspect of this integration.

Introduction to Two-Factor Authentication (2FA)
Two-factor authentication adds an extra layer of security by requiring users to provide a time-sensitive one-time password (OTP) generated by Google Authenticator or compatible apps in addition to their regular login credentials. Laravel Fortify supports 2FA natively, but setting it up with Google Authenticator involves specific implementation steps to provide a seamless and secure experience.

Step 1: Install Laravel Fortify and Prerequisites
Ensure Laravel Fortify is installed and configured for your Laravel application. If not installed, use Composer to include it:

bash
composer require laravel/fortify

Publish the Fortify resources using:

bash
php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"

Run the migration to add necessary fields (like `two_factor_secret` and `two_factor_recovery_codes`) to the users table by running migrations. Fortify includes a migration creating these fields.

Next, install the `pragmarx/google2fa-laravel` package, which simplifies integrating Google 2FA with Laravel:

bash
composer require pragmarx/google2fa-laravel

Publish its configuration file:

bash
php artisan vendor:publish --provider="PragmaRX\Google2FALaravel\ServiceProvider"

Step 2: Configure Fortify for Two-Factor Authentication
Enable the two-factor authentication feature in the `config/fortify.php` file by including the feature in the features array:

php
use Laravel\Fortify\Features;

'features' => [
    // other features
    Features::twoFactorAuthentication([
        'confirmPassword' => true,
    ]),
],

This activates Fortify's 2FA support. The `confirmPassword` option requires users to confirm their password before enabling 2FA.

Step 3: Customize User Model
Ensure your User model includes the `TwoFactorAuthenticatable` trait provided by Fortify:

php
use Laravel\Fortify\TwoFactorAuthenticatable;

class User extends Authenticatable
{
    use TwoFactorAuthenticatable;

    // Other model code
}

This trait gives the user model fields and methods needed for managing 2FA secrets and recovery codes.

Step 4: Migration Adjustment for Confirmation Status (Optional but Recommended)
By default, Fortify activates 2FA as soon as the secret key is generated, which can cause users to lock themselves out if they never complete the Google Authenticator setup properly. To prevent this, create an additional boolean field `two_factor_confirmed` in your users table migration:

php
Schema::table('users', function (Blueprint $table) {
    $table->boolean('two_factor_confirmed')->default(false)->after('two_factor_recovery_codes');
});

This field tracks whether a user has completed setup successfully, allowing additional confirmation before enforcing 2FA at login.

Step 5: Set up Routes and Views
Fortify lets you define custom views for enabling 2FA and for the 2FA challenge during login.

- Define a view to show the 2FA setup page where users can scan the QR code.
- Define a view for the 2FA challenge prompt during login.

You can register the view for the 2FA challenge in your `FortifyServiceProvider`:

php
Fortify::twoFactorChallengeView(function () {
    return view('auth.two-factor-challenge');
});

Create views to handle:

- Displaying the QR code and secret key.
- Accepting the OTP input for activation verification.
- Showing error or success messages appropriately.

Example Blade Template for Setup:

blade
@extends('layouts.app')

@section('content')

    Two-Factor Authentication Setup

    @if (session('status'))
        {{ session('status') }}
    @endif

    @if (!auth()->user()->two_factor_secret)
        
            @csrf
            Enable Two-Factor Authentication
        
    @else
        Scan the QR code below with your Google Authenticator app:
        {!! auth()->user()->twoFactorQrCodeSvg() !!}
        
        
            @csrf
            
            Confirm
        
    @endif

@endsection

Step 6: Controller Logic for Enabling, Confirming, and Disabling 2FA
Create a controller to handle the 2FA activation, confirmation, and disabling processes. Fortify provides endpoints by default, but you might want custom logic to manage the confirmation step (if using `two_factor_confirmed`).

Example logic flow:

- When the user clicks to enable 2FA, generate a secret key and save it to the user but do not mark 2FA as confirmed yet.
- Show the QR code and a form to enter the OTP generated by the app.
- When the user submits the OTP, verify it using the google2fa package's `verifyKey` method.
- If valid, update `two_factor_confirmed` to true.
- If invalid, prompt the user for a retry.

Step 7: Middleware to Protect Routes
Create middleware to ensure users with 2FA enabled and confirmed must complete 2FA on login before accessing protected routes.

Example middleware logic:

php
public function handle($request, Closure $next)
{
    $user = $request->user();

    if ($user && $user->two_factor_secret && !$request->session()->get('two_factor_passed')) {
        // This prevents access before successful 2FA verification
        return redirect()->route('two-factor.login');
    }

    return $next($request);
}

Attach this middleware to routes needing protection.

Step 8: Challenge and Verification during Login
When a user with 2FA enabled logs in, Fortify automatically triggers the 2FA challenge. The user is prompted to enter the OTP generated by Google Authenticator.

The challenge view captures the OTP and sends it to Fortify's default endpoint for verification.

On successful verification, a session flag is set (e.g., `two_factor_passed`) allowing the user to proceed.

Step 9: Recovery Codes
Fortify supports recovery codes for 2FA fallback. These codes can be generated and shown to the user when enabling 2FA. Store them securely and offer UI options for regenerating or viewing them again.

Step 10: UX Considerations and Security Best Practices
- Warn users to save recovery codes.
- Allow easy disabling of 2FA with password confirmation.
- Rate-limit OTP inputs to prevent brute force attacks.
- Ensure secure HTTPS for all flows.
- Implement notifications such as email alerts on 2FA status changes.

Step 11: Alternative Manual Google2FA Package Integration (Optional)
If not using Fortify's native 2FA support, you can implement 2FA via the `pragmarx/google2fa-laravel` package manually:

- Generate secret keys via `$google2fa->generateSecretKey()`
- Generate QR codes via `$google2fa->getQRCodeUrl(...)` or inline images
- Verify OTP using `$google2fa->verifyKey($secret, $otp)`

You manage storing secrets, showing QR codes, and validating user inputs as described.

Summary Workflow:
1. User opts into 2FA.
2. Generate and save secret key.
3. Display QR code for Google Authenticator scan.
4. User submits OTP to confirm setup.
5. Once confirmed, 2FA is enforced on login.
6. On login, user enters OTP from Google Authenticator.
7. System verifies OTP, granting access if valid.
8. Recovery codes allow backup access if OTP unavailable.

This setup with Laravel Fortify and Google Authenticator ensures an industry-standard, secure 2FA solution integrated into your Laravel application's authentication process.

Additional References for Implementation and Troubleshooting:
- Laravel official Fortify documentation on 2FA
- pragmarx/google2fa-laravel GitHub repository and docs
- Example open-source projects and tutorials implementing 2FA with Laravel Fortify
- Community discussions on edge cases to prevent user lockout and enhance user experience

This comprehensive guide enables developers to implement Google Authenticator with Laravel Fortify successfully while customizing confirmation flows and managing security aspects effectively for production-ready applications.