Implement Two-Factor Authentication in Laravel 12

Hi there! As a developer, I know how important it is to keep user data safe. That’s why I’m excited to share this guide on implementing Two-Factor Authentication (2FA) in Laravel 12. 2FA adds an extra layer of security by requiring users to provide a second form of verification, like a code from their phone, in addition to their password.

In this article, I’ll walk you through setting up 2FA using Laravel Fortify and Google Authenticator in simple, beginner-friendly steps. Whether you’re building a small app or a large platform, this guide will help you make your application more secure.

Step-by-Step Guide to Implementing 2FA in Laravel 12

Implement Two-Factor Authentication in Laravel 12

Step 1: Set Up a New Laravel 12 Project

First, I need to create a fresh Laravel 12 project. If you already have a project, you can skip this step. Open your terminal and run:

composer create-project laravel/laravel laravel-2fa
cd laravel-2fa

This command sets up a new Laravel project named laravel-2fa. Make sure you have Composer installed and a database ready (I’m using MySQL for this guide, but you can use any database supported by Laravel).

Step 2: Install and Configure Laravel Fortify

Laravel Fortify is a great package for handling authentication features, including 2FA. To install it, run:

composer require laravel/fortify

Next, publish Fortify’s configuration and migration files:

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

This creates a config/fortify.php file and adds 2FA-related columns to the users table via a migration. Run the migration to update your database:

php artisan migrate

In the config/fortify.php file, enable the 2FA feature by adding two-factor-authentication to the features array:

'features' => [
    Features::registration(),
    Features::resetPasswords(),
    Features::emailVerification(),
    Features::twoFactorAuthentication([
        'confirm' => true,
        'confirmPassword' => true,
    ]),
],

This enables 2FA and requires users to confirm their password before enabling it.

Step 3: Update the User Model

To support 2FA, your User model needs to use the TwoFactorAuthenticatable trait. Open app/Models/User.php and update it like this:

<?php
namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Fortify\TwoFactorAuthenticatable;

class User extends Authenticatable
{
    use Notifiable, TwoFactorAuthenticatable;

    protected $fillable = [
        'name', 'email', 'password',
    ];

    protected $hidden = [
        'password', 'remember_token', 'two_factor_recovery_codes', 'two_factor_secret',
    ];
}

This adds 2FA capabilities to your User model, allowing it to store a 2FA secret and recovery codes.

Step 4: Set Up Authentication Scaffolding with Laravel Breeze

To make things easier, I’ll use Laravel Breeze to set up basic authentication views (login, registration, etc.). Install Breeze:

composer require laravel/breeze --dev
php artisan breeze:install
npm install && npm run dev
php artisan migrate

This generates authentication routes, controllers, and Blade views. You’ll also need to compile the front-end assets using npm run dev.

Step 5: Configure 2FA Views

Fortify automatically handles the 2FA challenge screen, but I need to define the view for it. In app/Providers/FortifyServiceProvider.php, specify the 2FA challenge view in the boot method:

use Laravel\Fortify\Fortify;

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

Create a new Blade file at resources/views/auth/two-factor-challenge.blade.php:

@extends('layouts.app')

@section('content')
<div class="container">
    <h1>Two-Factor Authentication</h1>
    <p>Please enter the code from your authenticator app.</p>

    @if ($errors->any())
        <div class="alert alert-danger">
            {{ $errors->first() }}
        </div>
    @endif

    <form method="POST" action="{{ route('two-factor.login') }}">
        @csrf
        <div class="form-group">
            <label for="code">Code</label>
            <input type="text" name="code" id="code" class="form-control" required>
        </div>
        <button type="submit" class="btn btn-primary">Verify</button>
    </form>
</div>
@endsection

This creates a simple form where users can enter their 2FA code.

Step 6: Enable 2FA for Users

Users need a way to enable or disable 2FA in their account settings. Create a Blade view at resources/views/profile/two-factor-authentication.blade.php:

@extends('layouts.app')

@section('content')
<div class="container">
    <h1>Manage Two-Factor Authentication</h1>

    @if (session('status') == 'two-factor-authentication-enabled')
        <div class="alert alert-success">
            2FA has been enabled! Scan the QR code with your authenticator app.
        </div>
    @endif

    <form method="POST" action="{{ route('two-factor.enable') }}">
        @csrf
        <button type="submit" class="btn btn-primary">Enable 2FA</button>
    </form>

    @if (auth()->user()->two_factor_secret)
        <h3>Recovery Codes</h3>
        <ul>
            @foreach (auth()->user()->twoFactorRecoveryCodes() as $code)
                <li>{{ $code }}</li>
            @endforeach
        </ul>
        <form method="POST" action="{{ route('two-factor.recovery-codes') }}">
            @csrf
            <button type="submit" class="btn btn-secondary">Regenerate Recovery Codes</button>
        </form>
        <form method="POST" action="{{ route('two-factor.disable') }}">
            @csrf
            @method('DELETE')
            <button type="submit" class="btn btn-danger">Disable 2FA</button>
        </form>
    @endif
</div>
@endsection

This view allows users to enable 2FA, view recovery codes, regenerate them, or disable 2FA. Add a link to this page in your app’s navigation (e.g., in resources/views/layouts/app.blade.php).

Step 7: Test the 2FA Setup

Now, let’s test everything. Start your Laravel server:

php artisan serve
  1. Register a new user via /register.
  2. Log in and navigate to the 2FA settings page.
  3. Click “Enable 2FA” to generate a QR code. Scan it with an authenticator app like Google Authenticator.
  4. Log out and log back in. After entering your credentials, you’ll be prompted to enter the 2FA code from your app.

If everything works, congratulations! Your app now has 2FA.

Conclusion

Implementing Two-Factor Authentication in Laravel 12 is a straightforward way to boost your application’s security. By using Laravel Fortify, I was able to add 2FA with minimal effort, ensuring users’ accounts are protected even if their passwords are compromised. This guide covered setting up a Laravel project, configuring Fortify, creating necessary views, and testing the 2FA flow. With this setup, you can give your users peace of mind and make your app more secure.

FAQs

Q1: What is Two-Factor Authentication (2FA)?
A: 2FA is a security feature that requires users to provide two forms of identification to log in, typically a password and a code from an authenticator app.

Q2: Why should I use 2FA in my Laravel app?
A: 2FA adds an extra layer of security, making it harder for attackers to access user accounts, even if they know the password.

Q3: Can I use other authenticator apps besides Google Authenticator?
A: Yes, any TOTP-compatible app, like Authy or Microsoft Authenticator, will work with this setup.

Q4: What are recovery codes, and why are they important?
A: Recovery codes are one-time-use codes that allow users to log in if they lose access to their authenticator app. Store them securely!

Q5: Do I need Laravel Fortify for 2FA?
A: No, you can use other packages like pragmarx/google2fa-laravel, but Fortify is recommended for its integration with Laravel’s ecosystem.


You might also like :

techsolutionstuff

Techsolutionstuff | The Complete Guide

I'm a software engineer and the founder of techsolutionstuff.com. Hailing from India, I craft articles, tutorials, tricks, and tips to aid developers. Explore Laravel, PHP, MySQL, jQuery, Bootstrap, Node.js, Vue.js, and AngularJS in our tech stack.

RECOMMENDED POSTS

FEATURE POSTS