Your Guide to Laravel Excellence

How to Add Two-Factor Authentication (2FA) in Laravel Fortify

How to Add Two-Factor Authentication (2FA) in Laravel Fortify

In this step-by-step guide, I’ll learn the through the process of enabling Two-Factor Authentication in Laravel Fortify. In this tutorial, we’ll be add 2FA in Laravel application, adding an extra layer of protection for your users.

Install Laravel Fortify

composer require laravel/fortify

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

php artisan migrate

Ensure Fortify is registered in bootstrap/providers.php:

// bootstrap\providers.php
return [
    App\Providers\AppServiceProvider::class,
    App\Providers\FortifyServiceProvider::class,
];

Set Up 2FA with Fortify

Step 1: Add Columns for 2FA

Fortify requires two columns in the users table for 2FA:

  • two_factor_secret: Stores the secret key for 2FA.

  • two_factor_recovery_codes: Stores recovery codes.

php artisan make:migration add_two_factor_columns_to_users_table --table=users

Update the migration:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->text('two_factor_secret')->nullable();
        $table->text('two_factor_recovery_codes')->nullable();
    });
}

Run the migration:

php artisan migrate

Step 2: Enable 2FA in User Model

Update the User model to use the Laravel\Fortify\TwoFactorAuthenticatable trait:

use Laravel\Fortify\TwoFactorAuthenticatable;

class User extends Authenticatable
{
    use TwoFactorAuthenticatable;
    // Other traits...
}

Step 3: Configure Fortify

Enable the two-factor-authentication feature in the features array:

'features' => [
    Features::registration(),
    Features::resetPasswords(),
    // Features::emailVerification(),
    Features::updateProfileInformation(),
    Features::updatePasswords(),

    // Enable the two-factor-authentication feature
    Features::twoFactorAuthentication([
        'confirm' => true,
        'confirmPassword' => true,
        // 'window' => 0,
    ]),
],

Set Up Views and Routes

Activate Two-Factor Authentication

we need to send a POST request to /user/two-factor-authentication, which is handled by Fortify.

<form class="d-inline" action="/user/two-factor-authentication" method="POST">
    @csrf
    <button class="btn btn-primary" type="submit">Activate 2FA</button>
</form>

Next, you should display the two factor authentication QR code for the user to scan into their authenticator application.

Scan QR Code to Set Up Two-Factor Authentication

In order to validate Two Factor Authentication, please scan this QR code with Google Authenticator or Duo and enter the validation code below :

<div class="mb-4">
    {!! auth()->user()->twoFactorQrCodeSvg() !!}
</div>
<div class="row justify-content-center">
    <form action="{{ route('two-factor.confirm') }}" method="POST">
        @csrf
        <label for="code" class="form-label">Code</label>
        <div class="input-group mb-3">
            <input class="form-control" id="code" type="text" name="code" required />
            <button class="btn btn-primary" type="submit">Validate 2FA</button>
        </div>
    </form>
</div>
Route::post('/two-factor-confirm', function (Request $request) {
    $confirmed = $request->user()->confirmTwoFactorAuth($request->code);

    if (!$confirmed) {
        return back()->withErrors('Invalid Two Factor Authentication code');
    }

    return back();
})->name('two-factor.confirm');

Disable Two-Factor Authentication To turn off two-factor authentication, your app needs to send a DELETE request to the /user/two-factor-authentication endpoint. Keep in mind, Fortify requires the user to confirm their password before making this request.

<form class="d-inline" action="/user/two-factor-authentication" method="POST">
    @csrf
    @method('DELETE')
    <button class="btn btn-danger" type="submit">Disable 2FA</button>
</form>

Recommeded Posts

Multi-Guard Authentication with Laravel Fortify

Multi-Guard Authentication with Laravel Fortify

Multi-Guard Authentication with Laravel Fortify

1 month ago Read article →
Role-Based Redirects in Laravel Fortify with Spatie Permissions

Role-Based Redirects in Laravel Fortify with Spatie Permissions

Role-Based Redirects in Laravel Fortify with Spatie Permissions

1 month ago Read article →