Laravel Google 2FA Authentication Tutorial Example
Hey Folks,
This post will give you an example of laravel google 2fa authentication. step by step explain two factor authentication using google authenticator in laravel. In this article, we will implement a laravel two factor authentication with google authenticator. This post will give you a simple example of laravel 2fa google authenticator.
You can add google authenticator with laravel 6, laravel 7, laravel 8, laravel 9, laravel 10 and laravel 11 versions.
Security is a primary feature of all websites. Laravel is a secure framework and it provides security features. But if you want to make more secure your laravel app then you can also use Google 2FA Authenticator in laravel App. In this tutorial, I will show you step by step how to add two factor authentication using google authenticator in laravel.
Google2FA is a PHP implementation of the Google Two-Factor Authentication Module, supporting the HMAC-Based One-time Password (HOTP) algorithm specified in RFC 4226 and the Time-based One-time Password (TOTP) algorithm specified in RFC 6238.
Google Authentication Apps
To use the two-factor authentication, the user will have to install a Google Authenticator compatible app. Here are a few:
How the TOTP works is that the server generates a secret key. This secret key is then passed to the user. The secret key is used in combination with the current Unix timestamp to generate a six digit number, using a keyed-hash message authentication code (HMAC) based algorithm. This six digit number is the OTP. It changes every 30 seconds.
So, without further ado, let's see the below code:
Preview:
Step 1: Install Laravel
This is optional; however, if you have not created the laravel app, then you may go ahead and execute the below command:
composer create-project laravel/laravel example-app
Step 2: Setup Database Configuration
After successfully installing the laravel app then after configuring the database setup. We will open the ".env" file and change the database name, username and password in the env file.
.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=Enter_Your_Database_Name
DB_USERNAME=Enter_Your_Database_Username
DB_PASSWORD=Enter_Your_Database_Password
Step 3: Install Auth Scaffold
Laravel's laravel/ui package provides a quick way to scaffold all of the routes and views you need for authentication using a few simple commands:
composer require laravel/ui
Next, we need to generate auth scaffold with bootstrap, so let's run the below command:
php artisan ui bootstrap --auth
Then, install npm packages using the below command:
npm install
At last, built bootstrap CSS using the below command:
npm run build
Step 4: Install Google Two-Factor Authentication Package
In this step, we will install pragmarx/google2fa-laravel and bacon/bacon-qr-code that way we can use methods of google authentication. so let's run the below command:
composer require pragmarx/google2fa-laravel
composer require bacon/bacon-qr-code
Next, we need to publish configuration file, so let's run the below command:
php artisan vendor:publish --provider="PragmaRX\Google2FALaravel\ServiceProvider"
Step 5: Add 2fa Middleware
here, we will add "2fa" middleware in Kernel.php file. 2fa middleware added by google2fa-laravel composer package. so let's register it.
app/Http/Kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
...
...
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
...
'2fa' => \PragmaRX\Google2FALaravel\Middleware::class,
];
}
Step 6: Create Migration
Here, we have to create new migration for add "google2fa_secret" column in users table using Laravel php artisan command, so first fire bellow command:
php artisan make:migration add_google_2fa_columns
After this command you will find one file in the following path "database/migrations" and you have to put the below code in your migration file.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->text('google2fa_secret')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
}
};
Step 7: Update Model
In this step, we will update User model file. so let's update as the below:
app/Models/User.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Database\Eloquent\Casts\Attribute;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'password',
'google2fa_secret'
];
/**
* The attributes that should be hidden for serialization.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* Interact with the user's first name.
*
* @param string $value
* @return \Illuminate\Database\Eloquent\Casts\Attribute
*/
protected function google2faSecret(): Attribute
{
return new Attribute(
get: fn ($value) => decrypt($value),
set: fn ($value) => encrypt($value),
);
}
}
Step 8: Create Routes
In this step, we will create three routes for v complete registration process with auth routes. So, let's add a new route to that file.
routes/web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Auth\RegisterController;
use App\Http\Controllers\HomeController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::middleware(['2fa'])->group(function () {
Route::get('/home', [HomeController::class, 'index'])->name('home');
Route::post('/2fa', function () {
return redirect(route('home'));
})->name('2fa');
});
Route::get('/complete-registration', [RegisterController::class, 'completeRegistration'])->name('complete.registration');
Step 9: Update Controller File
in the next step, now we have need to update RegisterController, So let's create a controller:
app/Http/Controllers/Auth/RegisterController.php
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\Models\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers {
register as registration;
}
/**
* Where to redirect users after registration.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:6', 'confirmed'],
]);
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return \App\Models\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'google2fa_secret' => $data['google2fa_secret'],
]);
}
/**
* Write code on Method
*
* @return response()
*/
public function register(Request $request)
{
$this->validator($request->all())->validate();
$google2fa = app('pragmarx.google2fa');
$registration_data = $request->all();
$registration_data["google2fa_secret"] = $google2fa->generateSecretKey();
$request->session()->flash('registration_data', $registration_data);
$QR_Image = $google2fa->getQRCodeInline(
config('app.name'),
$registration_data['email'],
$registration_data['google2fa_secret']
);
return view('google2fa.register', ['QR_Image' => $QR_Image, 'secret' => $registration_data['google2fa_secret']]);
}
/**
* Write code on Method
*
* @return response()
*/
public function completeRegistration(Request $request)
{
$request->merge(session('registration_data'));
return $this->registration($request);
}
}
Step 10: Create Blade File
In this step, we need to create three blade file with index.blade.php and register.blade.php files in google2fa, so let's update following code on it:
resources/views/google2fa/index.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center align-items-center " style="height: 70vh;S">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading font-weight-bold">Register</div>
<hr>
@if($errors->any())
<div class="col-md-12">
<div class="alert alert-danger">
<strong>{{$errors->first()}}</strong>
</div>
</div>
@endif
<div class="panel-body">
<form class="form-horizontal" method="POST" action="{{ route('2fa') }}">
{{ csrf_field() }}
<div class="form-group">
<p>Please enter the <strong>OTP</strong> generated on your Authenticator App. <br> Ensure you submit the current one because it refreshes every 30 seconds.</p>
<label for="one_time_password" class="col-md-4 control-label">One Time Password</label>
<div class="col-md-6">
<input id="one_time_password" type="number" class="form-control" name="one_time_password" required autofocus>
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4 mt-3">
<button type="submit" class="btn btn-primary">
Login
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
resources/views/google2fa/register.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-12 mt-4">
<div class="card card-default">
<h4 class="card-heading text-center mt-4">Set up Google Authenticator</h4>
<div class="card-body" style="text-align: center;">
<p>Set up your two factor authentication by scanning the barcode below. Alternatively, you can use the code <strong>{{ $secret }}</strong></p>
<div>
{!! $QR_Image !!}
</div>
<p>You must set up your Google Authenticator app before continuing. You will be unable to login otherwise</p>
<div>
<a href="{{ route('complete.registration') }}" class="btn btn-primary">Complete Registration</a>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
Run Laravel App:
All the required steps have been done, now you have to type the given below command and hit enter to run the Laravel app:
php artisan serve
Now, Go to your web browser, type the given URL and view the app output:
http://localhost:8000/
You can download code from github: https://github.com/savanihd/laravel-google-2fa
I hope it can help you...
Hardik Savani
I'm a full-stack developer, entrepreneur and owner of ItSolutionstuff.com. I live in India and I love to write tutorials and tips that can help to other artisan. I am a big fan of PHP, Laravel, Angular, Vue, Node, Javascript, JQuery, Codeigniter and Bootstrap from the early stage. I believe in Hardworking and Consistency.
We are Recommending you
- Laravel Cashier Stripe Subscription Example Tutorial
- How to Merge Multiple PDF Files in Laravel 9?
- Laravel 9 Multi Auth: Create Multiple Authentication in Laravel
- Laravel 9 REST API with Passport Authentication Tutorial
- Laravel 9 REST API Authentication using Sanctum Tutorial
- Laravel Two Factor Authentication using Email Tutorial
- How to Add Two Factor Authentication with SMS in Laravel?
- Laravel Sanctum SPA API Authentication Example
- Laravel 8 Multi Auth (Authentication) Tutorial
- Laravel Login with Twitter OAuth Tutorial
- Laravel Login with Google Account Tutorial