Blog Detail


How to add Two Factor Authentication Easily in Laravel 8 cover image

How to add Two Factor Authentication Easily in Laravel 8

Michael Dzjaparidze introduced a two-factor authentication package for Laravel. This package currently only works out of the box with the MessageBird Verify API or the 'null' driver that goes through all the steps of the two-factor authentication process without actually doing any real verification. This could be useful for testing purposes. You can, however, specify a custom provider yourself. This package uses throttling to limit the number of unsuccessful authentication attempts in a certain amount of time.


To install using Composer run:

composer require michaeldzjap/twofactor-auth

If you want to use MessageBird Verify as the two-factor authentication provider then you also need to install the MessageBird PHP API:

composer require messagebird/php-rest-api

and don't forget to add your MESSAGEBIRD_ACCESS_KEY and TWO_FACTOR_AUTH_DRIVER=messagebird variables to the .env. If you instead wish to use the null driver (default) then do NOT define the TWO_FACTOR_AUTH_DRIVER variable in your .env.

From Laravel 7 and onwards you will also need to install the laravel/ui package:

composer require laravel/ui

Add the service provider to the providers array in config/app.php:


Run the following artisan command to publish the configuration, language, and view files:

php artisan vendor:publish

Run the following artisan command to run the database migrations

php artisan migrate

This will add a mobile column to the users table and create a two_factor_auths table.

Add the following trait to your User model:

use MichaelDzjap\TwoFactorAuth\TwoFactorAuthenticable;

class User extends Authenticatable
    use Notifiable, TwoFactorAuthenticable;

Optionally, you might want to add 'mobile' to your $fillable array.

Changes to the Login Process

The following two-factor authentication routes will be added automatically:

    'middleware' => ['web', 'guest'],
    'namespace' => 'App\Http\Controllers\Auth',
], function () use ($router) {
    $router->get('/auth/token', 'TwoFactorAuthController@showTwoFactorForm')->name('auth.token');
    $router->post('/auth/token', 'TwoFactorAuthController@verifyToken');

The first route is the route the user will be redirected to once the two-factor authentication process has been initiated. The second route is used to verify the two-factor authentication token that is to be entered by the user. The showTwoFactorForm controller method does exactly what it says. There do exist cases where you might want to respond differently, however. For instance, instead of loading a view, you might just want to return a json response. In that case, you can simply overwrite showTwoFactorForm in the TwoFactorAuthController to be discussed below.

Add the following import to LoginController:

use MichaelDzjap\TwoFactorAuth\Contracts\TwoFactorProvider;

class LoginController extends Controller

and also add the following functions:

 * The user has been authenticated.
 * @param  \Illuminate\Http\Request  $request
 * @param  mixed  $user
 * @return mixed
protected function authenticated(Request $request, $user)
    if (resolve(TwoFactorProvider::class)->enabled($user)) {
        return self::startTwoFactorAuthProcess($request, $user);

    return redirect()->intended($this->redirectPath());


 * Log out the user and start the two-factor authentication state.
 * @param  \Illuminate\Http\Request $request
 * @param  \App\Models\User $user
 * @return \Illuminate\Http\Response
private function startTwoFactorAuthProcess(Request $request, $user)
    // Logout user, but remember user id
        'two-factor:auth', array_merge(['id' => $user->id], $request->only('email', 'remember'))


    return redirect()->route('auth.token');

and lastly

 * Provider-specific two-factor authentication logic. In the case of MessageBird
 * we just want to send an authentication token via SMS.
 * @param  \App\Models\User $user
 * @return mixed
private function registerUserAndSendToken(User $user)
    // Custom, provider dependend logic for sending an authentication token
    // to the user. In the case of MessageBird Verify this could simply be
    // resolve(TwoFactorProvider::class)->sendSMSToken($this->user)
    // Here we assume this function is called from a queue'd job
    dispatch(new SendSMSToken($user));

You can discard the third function if you do not want to send a two-factor authentication token automatically after a successful login attempt. Instead, you might want the user to instantiate this process from the form of him/herself. In that case, you would have to add the required route and controller method to trigger this function yourself. The best place for this would be the TwoFactorAuthController to be discussed next.

Add a TwoFactorAuthController in app/Http/Controllers/Auth with the following content:


namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use MichaelDzjap\TwoFactorAuth\Http\Controllers\TwoFactorAuthenticatesUsers;

class TwoFactorAuthController extends Controller
    use TwoFactorAuthenticatesUsers;

     * The maximum number of attempts to allow.
     * @var int
    protected $maxAttempts = 5;

     * The number of minutes to throttle for.
     * @var int
    protected $decayMinutes = 1;

     * Where to redirect users after two-factor authentication passes.
     * @var string
    protected $redirectTo = RouteServiceProvider::HOME;

If you want to give textual feedback to the user when two-factor authentication fails due to an expired token or when throttling kicks in you may want to add this to resources/views/auth/login.blade.php:

<form class="form-horizontal" role="form" method="POST" action="{{ route('login') }}">

    @if ($errors->has('token'))
        <div class="alert alert-danger alert-dismissible fade show" role="alert">
            <strong>{{ $errors->first('token') }}</strong>
            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                <span aria-hidden="true">&times;</span>

You can Visit more details on Github.

Published at : 01-12-2021

Author : Rizwan Aslam
Rizwan Aslam

I am a highly results-driven professional with 12+ years of collective experience in the grounds of web application development especially in laravel, native android application development in java, and desktop application development in the dot net framework. Now managing a team of expert developers at Codebrisk.

Launch project