One-time password (OTP) verification is a commonly used authentication method that requires users to enter a temporary code sent to their mobile phone number via SMS. This adds an extra layer of security to your Laravel application. In this guide, we will use Twilio, a cloud communication platform, to send SMS messages to users with OTP codes.
Prerequisites
Before we begin, make sure you have the following installed:
- PHP 7.4 or later
- Composer
- Laravel 8.x
- Twilio account
Step 1: Create Laravel Project
First, we need to create a new Laravel project using Composer. Open your terminal and run the following command:
composer create-project --prefer-dist laravel/laravel otp-verification
This will create a new Laravel project in a directory named otp-verification
.
Read Also : how to add textlocal otp verification in laravel 8
Step 2: Configure Database
Next, we need to configure our database settings. Open the .env
file in the root directory of your project and set the following:
DB_DATABASE=your_database_nameDB_USERNAME=your_database_usernameDB_PASSWORD=your_database_password
Make sure to replace your_database_name
, your_database_username
, and your_database_password
with your actual database credentials.
Step 3: Create User Model and Migration
Now, let’s create a User
model and migration using the following command:
php artisan make:model User -m
This will create a new User
model in the app
directory and a migration file in the database/migrations
directory. Open the migration file and add the following columns to the up
method:
Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('phone_number')->unique(); $table->timestamps();});
This will create a users
table with id
, name
, phone_number
, and timestamps
columns.
Run the migration using the following command:
php artisan migrate
Step 4: Install Twilio SDK
Next, we need to install the Twilio PHP SDK to send SMS messages. Run the following command to install the SDK:
composer require twilio/sdk
This will install the Twilio PHP SDK in the vendor
directory of your project.
Step 5: Create OTP Model and Migration
We need to create an OTP
model and migration to store the OTP codes for each user. Run the following command to create the model and migration:
php artisan make:model OTP -m
This will create an OTP
model in the app
directory and a migration file in the database/migrations
directory. Open the migration file and add the following columns to the up
method:
Schema::create('otps', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('user_id'); $table->string('otp'); $table->timestamp('expires_at'); $table->timestamps();});
This will create an otps
table with id
, user_id
, otp
, expires_at
, and timestamps
columns.
Run the migration using the following command:
php artisan migrate
Step 6: Generate OTP Code
Now, let’s create a method to generate a random OTP code. Open the OTPController
in the app/Http/Controllers
directory and add the following method to generate a random 6-digit OTP code:
protected function generateOTP(){ return rand(100000, 999999);}
This method generates a random 6-digit number between 100000 and 999999.
Step 7: Send OTP via SMS
We can now use the Twilio PHP SDK to send an SMS message to the user’s phone number with the OTP code. To do this, we need to add the following method to the OTPController
:
use Twilio\Rest\Client;protected function sendOTP($phone_number, $otp){ $sid = env('TWILIO_ACCOUNT_SID'); $token = env('TWILIO_AUTH_TOKEN'); $from = env('TWILIO_PHONE_NUMBER'); $client = new Client($sid, $token); $message = "Your OTP code is: " . $otp; $client->messages->create( $phone_number, [ 'from' => $from, 'body' => $message, ] );}
This method uses the Twilio PHP SDK to send an SMS message to the user’s phone number with the OTP code. We get the Twilio account SID, auth token, and phone number from the .env
file.
Step 8: Create OTP Verification Form
We now need to create a form for the user to enter their phone number and receive the OTP code. Create a new blade view file otp-verification.blade.php
in the resources/views
directory with the following content:
<!DOCTYPE html><html><head> <title>OTP Verification</title></head><body> <h1>OTP Verification</h1> <form method="post" action="{{ route('otp.send') }}"> @csrf <label for="phone_number">Phone Number</label> <input type="text" name="phone_number" id="phone_number"> <button type="submit">Send OTP</button> </form></body></html>
This form has a phone_number
input field and a submit button that sends the phone number to the OTPController
using the otp.send
route.
Step 9: Implement OTP Verification Logic
Now, let’s implement the logic to generate and store the OTP code, and verify it when the user enters it on the verification page. Add the following methods to the OTPController
:
use Carbon\Carbon;use Illuminate\Http\Request;public function sendOTP(Request $request){ $request->validate([ 'phone_number' => 'required|numeric|digits_between:8,12|unique:users,phone_number', ]); $user = User::where('phone_number', $request->phone_number)->first(); if (!$user) { $user = User::create([ 'phone_number' => $request->phone_number, ]); } $otp = $this->generateOTP(); OTP::create([ 'user_id' => $user->id, 'otp' => $otp, 'expires_at' => Carbon::now()->addMinutes(5), ]); $this->sendOTP($request->phone_number, $otp); return redirect()->route('otp.verify');}public function showVerifyForm(){ return view('verify-otp');}public function verifyOTP(Request $request){ $request->validate([ 'phone_number' => 'required|numeric|digits_between:8,12', 'otp' => 'required|numeric|digits:6', ]); $user = User::where('phone_number', $request->phone_number)->first()if (!$user) { return redirect()->back()->with('error', 'Invalid phone number');}$otp = OTP::where('user_id', $user->id) ->where('otp', $request->otp) ->where('expires_at', '>', Carbon::now()) ->first();if (!$otp) { return redirect()->back()->with('error', 'Invalid OTP code');}$otp->delete();return redirect()->route('home')->with('success', 'OTP verification successful');}
The `sendOTP` method first validates the `phone_number` input field and checks if the user with the given phone number already exists in the database. If not, it creates a new user record with the phone number.
Next, it generates a new OTP code, stores it in the `otps` table with an expiration time of 5 minutes, and sends it to the user’s phone number using the `sendOTP` method we created earlier.
The `showVerifyForm` method simply returns the `verify-otp.blade.php` view we created earlier.
The `verifyOTP` method validates the `phone_number` and `otp` input fields, and checks if the OTP code matches the one stored in the `otps` table for the given user and has not expired. If everything checks out, it deletes the OTP record from the database and redirects the user to the home page with a success message.
Step 10: Create Routes
Finally, we need to create the routes for the OTP verification feature. Add the following routes to the routes/web.php
file:
use App\Http\Controllers\OTPController;Route::get('/', function () { return view('welcome');});Route::get('/home', function () { return view('home');})->name('home');Route::get('/otp/verify', [OTPController::class, 'showVerifyForm'])->name('otp.verify');Route::post('/otp/send', [OTPController::class, 'sendOTP'])->name('otp.send');Route::post('/otp/verify', [OTPController::class, 'verifyOTP'])->name('otp.verify');
We have created three routes:
/otp/verify
– GET request to show the OTP verification form/otp/send
– POST request to send the OTP code to the user’s phone number/otp/verify
– POST request to verify the OTP code entered by the user
Conclusion
In this article, we have seen how to implement mobile OTP verification in Laravel 8 step by step. We have used Twilio to send SMS messages, Eloquent ORM to interact with the database, and Carbon to handle dates and times. We have also seen how to use middleware to protect routes and how to create and validate forms. By following these steps, you can easily implement OTP verification in your Laravel application and secure your users’ accounts.
Comments
Post a Comment