I will show you how we can add SMS OTP authentication using Twilio using twilio verify method. Let’s start with steps-
- Install Laravel
- Install JetStream
- Create Middleware
- Create Controller and view file for Verification
- Run The app and Test.
Install Laravel
I will install latest Laravel using composer.
composer create-project laravel/laravel OTP-Auth
Install JetStream
On above step you already installed Laravel now to to your project directory and install JetStream using below command.
composer require laravel/jetstream
and then
php artisan jetstream:install inertia
now, Finalizing The Installation
npm install npm run build
set database connection in .env file and then run below command
php artisan migrate
Create Middleware
Here i will create an middleware and some update regarding Auth.
For creating middleware use below command.
php artisan make:middleware Check2FA
a new php file is created inside you app/Http/Middleware/Check2FA.php
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; class Check2FA { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse */ public function handle(Request $request, Closure $next) { return $next($request); } }
Now update the handle function
public function handle(Request $request, Closure $next) { if (!Session::has('user_2fa')) { auth()->user()->generateCode(); return redirect()->route('2fa.index'); } return $next($request); }
Now your middleware will looks like below
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Session; class Check2FA { public function handle(Request $request, Closure $next) { if (!Session::has('user_2fa')) { return redirect()->route('2fa.index'); } return $next($request); } }
Create Controller and function for Verification
Create a controller using the below command.
php artisan make:controller TwoFAController
now update above class with below.
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\User; use Session; class TwoFAController extends Controller { public function index() { return view('2fa.index'); } public function verify(Request $request) { $request->validate([ 'pin'=>'required', ]); $find = User::where('id', auth()->user()->id) ->first(); $mobile=auth()->user()->phone; if(!empty($find)) { $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => 'https://verify.twilio.com/v2/Services/VAc87a93cd230ccc8ed599ade50737626c/VerificationCheck', CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => array('To' => $mobile, 'Code' => trim($request->pin)), CURLOPT_HTTPHEADER => array( 'Authorization: Basic QUNmMmVmNWRmMDUxZGY4NWE3MDlmMDJkMjQxZTQwMzliMjo3NjUxMjViMWU1NmNiNWY5OWVkNjk5NjXXXXXXXXXX==' ), )); $response = curl_exec($curl); if(curl_errno($curl)) { $_SESSION[EW_SESSION_FAILURE_MESSAGE] = curl_error($curl); } else { $res = json_decode($response, true); if(isset($res['status']) && !empty($res['status']) && strtolower($res['status']) == 'approved' && isset($res['valid']) && $res['valid'] == true) { Session::put('user_2fa', auth()->user()->id); return redirect()->route('dashboard'); } else if(isset($res['status']) && !empty($res['status']) && strtolower($res['status']) == 'pending' && isset($res['valid']) && $res['valid'] == false) { return back()->with('error', 'Invalid pin.'); } else if(isset($res['message']) && !empty($res['message'])) { return back()->with('error', 'Pin has been expired.'); } else { return back()->with('error', 'Pin has been expired.'); } } curl_close($curl); } else { return back()->with('error', 'Pin has been expired.'); } } }
Above class i used phone at user model , so make sure you have to create phone column in database. like below image.
Set middleware on Kernal.php
'2fa' => \App\Http\Middleware\Check2FA::class,
like below image.
Now all done.
run using below command.
php artisan serv