Laravel 2 min read 555 views

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

Add an extra layer of security with TOTP-based two-factor authentication in your Laravel application.

E
2FA security

Step 1: Install Package

composer require pragmarx/google2fa-laravel
composer require bacon/bacon-qr-code

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

Step 2: Add Migration

Schema::table('users', function (Blueprint $table) {
    $table->string('google2fa_secret')->nullable();
    $table->boolean('two_factor_enabled')->default(false);
});

Step 3: Enable 2FA Controller

use PragmaRX\Google2FA\Google2FA;

class TwoFactorController extends Controller
{
    public function setup()
    {
        $google2fa = new Google2FA();
        $secret = $google2fa->generateSecretKey();

        session(['2fa_secret' => $secret]);

        $qrCodeUrl = $google2fa->getQRCodeUrl(
            config('app.name'),
            auth()->user()->email,
            $secret
        );

        return view('2fa.setup', compact('qrCodeUrl', 'secret'));
    }

    public function enable(Request $request)
    {
        $request->validate(['code' => 'required|digits:6']);

        $google2fa = new Google2FA();
        $secret = session('2fa_secret');

        if (!$google2fa->verifyKey($secret, $request->code)) {
            return back()->withErrors(['code' => 'Invalid code']);
        }

        auth()->user()->update([
            'google2fa_secret' => encrypt($secret),
            'two_factor_enabled' => true,
        ]);

        session()->forget('2fa_secret');

        return redirect()->route('profile')->with('success', '2FA enabled!');
    }

    public function verify(Request $request)
    {
        $request->validate(['code' => 'required|digits:6']);

        $google2fa = new Google2FA();
        $secret = decrypt(auth()->user()->google2fa_secret);

        if ($google2fa->verifyKey($secret, $request->code)) {
            session(['2fa_verified' => true]);
            return redirect()->intended('dashboard');
        }

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

Step 4: 2FA Middleware

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

        if ($user->two_factor_enabled && !session('2fa_verified')) {
            return redirect()->route('2fa.verify');
        }

        return $next($request);
    }
}

Step 5: Setup View

<div>
    <h2>Enable Two-Factor Authentication</h2>

    <p>Scan this QR code with your authenticator app:</p>

    <img src="https://chart.googleapis.com/chart?chs=200x200&chld=M|0&cht=qr&chl={{ urlencode($qrCodeUrl) }}">

    <p>Or enter this code manually: {{ $secret }}</p>

    <form method="POST" action="{{ route('2fa.enable') }}">
        @csrf
        <input type="text" name="code" placeholder="Enter 6-digit code">
        <button type="submit">Verify & Enable</button>
    </form>
</div>
Share this article:
ES

Written by Edrees Salih

Full-stack software engineer with 9 years of experience. Passionate about building scalable solutions and sharing knowledge with the developer community.

View Profile

Comments (0)

Leave a Comment

Your email will not be published.

No comments yet. Be the first to share your thoughts!