Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Implementing OTP in PHP Using Twilio

DZone 's Guide to

Implementing OTP in PHP Using Twilio

Learn how to use the popular Twilio platform and some PHP code to create a one time password generator for verifying your app's users.

· Web Dev Zone ·
Free Resource

Verifying a phone number using OTP (One Time Password) is a sure fire way to reduce spam coming to your website. In this article, we will discuss this topic in detail. We will be learning how we can set up our PHP code to send the OTP to mobile numbers and hence verify the user. We will be using Twilio as a third-party service to send the messages containing One Time Passwords (OTPs).

Table of Contents

  • 1. Prerequisites
  • 2. Configuring Twilio
  • 3. Workflow
  • 4. Actual Code
  • 5. Database Schema
  • 6. Code base and steps to run

Prerequisites:

Configuring Twilio

Actually, Twilio is a third-party tool which can be used to send text messages, IVR, and much more. There are many alternatives to Twilio but due to its seamless integration and a bit of my personal choice, we'll be using Twilio here in our article. Although Twilio is a paid tool, we can use a "free version" of it which, of course, has certain limitations but will suffice for our purposes. 

So let's go step by step:

  • Create an account on Twilio: First of all, you need to create an account by visiting this link. Don't worry, no credit card information is required at all at this moment. To learn more about the Free Trial Account of Twilio see this page.
  • Once you complete the signup process, proceed to the Console page on Twilio and note down your ACCOUNT SID and AUTH TOKEN. Both will be used by us later in our implementation.
  • You will be asked to select a "From Number." You should select the number as is because the number itself does not matter as of now. This is the number from which Twilio will be sending text messages on your behalf.
  • Now, as your account is a Trial account, you need to add at least one "To Number" here.  This is the same number to which messages would be sent. This particular step is required only for trial accounts.
  • After doing all the above steps, finally, your Twilio setup is complete.

You might see something similar in your Twilio Console:

TwlioDashboard

Workflow

You are obviously free to modify this as per your requirements, but I followed the below steps:

  • The user will be asked to enter their country code and mobile number. Please note that, as you are using a trial account of Twilio, the mobile number you mention here must be present in Verified Numbers of Your Twilio Account. 

Implementing OTP in PHP using Twilio

  • If the mobile number is not present in our database (which we would configure later in this post), we would insert that number into our database.

  • If the mobile number is already present in our database and it has already been verified (which we would check using the is_verified flag om our database), we would throw an error saying that "Number Already Verified."

  • It the mobile number is already present in our database and it has not been verified yet (which again, we would check using the is_verified flag from our database), we will trigger the "Send OTP" by hitting the actual Twilio OTP SDK and redirect the user to another page (verify.php). We also save the OTP sent in our database. As a side note, we will be generating a random four digit number as OTP using PHP's rand() function.

Sample OTP Received

  • After the user has received the above message, they can enter the OTP  on their mobile number and click verify.

Implementing OTP in PHP using Twilio

  • We can check if the entered OTP is correct or not from our database. If the OTP is correct, we'll show the success message "Congrats, Your Mobile Number is Verified." Otherwise, would show an error, such as "Incorrect OTP."

Actual Code

We would be having 5 files:

  • index.html
 <html>  
   <body><br/><br/><br/>  
     <form action="send_otp.php" method="post">   
       Enter Country Code: <input type="text" name="country_code"><br/><br/>  
       Enter Phone Number: <input type="text" name="phone_number"><br/><br/>  
       Send OTP: <input type="submit">  
     </form>  
   </body>  
 </html>  
  • send_otp.php
 <?php  
 session_start();  
 require_once './vendor/autoload.php';  
 include ('db_conn.php');  
 use Twilio\Rest\Client;  
 $sid = $configVariables['sid'];  
 $token = $configVariables['token'];  
 $from = $configVariables['from'];  
 $countryCode = $_POST['country_code'];  
 $phoneNumber = $_POST['phone_number'];  
 processData($countryCode, $phoneNumber, $connection);  
 function processData($countryCode, $phoneNumber, $connection) {  
   $sql = "SELECT * FROM `users` WHERE `phone_number` = '$phoneNumber' LIMIT 1";  
   $isPhoneNumberPresent = mysqli_query($connection, $sql) or die(mysqli_error($connection));  
   if(mysqli_num_rows($isPhoneNumberPresent) > 0) {  
     $record = mysqli_fetch_assoc($isPhoneNumberPresent);  
     if($record['is_verified'] == '1') {  
       echo "Number Already Verified";die;  
     } else {  
       sendOTP($countryCode, $phoneNumber, $connection);  
       header('Location: /verify.php');   
     }  
   } else {  
     $sql = "INSERT INTO users VALUES(DEFAULT, '$phoneNumber', '0', '0')";  
     $isPhoneNumberPresent = mysqli_query($connection, $sql) or die(mysqli_error($connection));  
     sendOTP($countryCode, $phoneNumber, $connection);  
     header('Location: /verify.php');   
   }  
 }  
 function sendOTP($countryCode, $phoneNumber, $connection) {  
   try {  
     global $sid;  
     global $token;  
     global $from;  
     $client = new Client($sid , $token);  
     $otp = generateOTP();  
     $message = $client->messages  
          ->create($countryCode . $phoneNumber, // to  
               array("from" => $from, "body" => "Your One Time Password is " . $otp)  
          );    
     $sql = "UPDATE `users` SET `otp`=$otp WHERE `phone_number` = '$phoneNumber'";  
     $verified = mysqli_query($connection, $sql) or die(mysqli_error($connection));  
     $_SESSION['phoneNumber'] = $phoneNumber;           
   } catch(\Exception $ex) {  
     print_r($ex);die;  
   }  
 }  
 function generateOTP() {  
   return rand(1000, 9999);  
 }  
  • verify.php
 <?php   
   if(!isset($_POST['submit'])) {  
     ?>  
     <html>  
       <body><br/><br/><br/>    
         <form action="verify.php" method="post">   
           Enter Received OTP: <input type="text" name="otp"><br/><br/>  
           Verify: <input type="submit" name="submit">  
         </form>  
       </body>  
     </html>  
     <?php  
   }   
 ?>  
 <?php  
 session_start();  
 include ('db_conn.php');  
 $phoneNumber = $_SESSION['phoneNumber'];  
 if(isset($_POST['submit'])) {  
   $otp = $_POST['otp'];  
   $sql = "SELECT * FROM `users` WHERE `phone_number` = '$phoneNumber' AND `otp` = '$otp'";  
   $isOTPCorrect = mysqli_query($connection, $sql) or die(mysqli_error($connection));  
   if(mysqli_num_rows($isOTPCorrect) > 0) {  
     $record = mysqli_fetch_assoc($isOTPCorrect);  
     $sql = "UPDATE `users` SET `is_verified`='1' WHERE `phone_number` = '$phoneNumber'";  
     $verified = mysqli_query($connection, $sql) or die(mysqli_error($connection));  
     echo "Congrats, Your Mobile Number is Verified";die;  
   } else {  
     echo "Incorrect OTP";die;  
   }  
 }  
  • config.php
 <?php  
 return [  
   'db_username' => '<Your DB username here>',  
   'db_password' => '<Your DB password here>',  
   'db_name' => '<Your DB name here>',  
   'sid' => '<Your SID here>',  
   'token' => '<Your AuthToken here>',  
   'from' => '<Your From Number(with country code) here>'  
 ];  
  • db_conn.php
 <?php  
 $configVariables = include ('config.php');  
 $dbUserName = $configVariables['db_username'];  
 $dbPassword = $configVariables['db_password'];  
 $dbName = $configVariables['db_name'];  
 $connection = mysqli_connect('localhost', $dbUserName, $dbPassword, $dbName) or die('could not connect to dataabase');  

Database Schema

For the sake of simplicity, I have created only one table, named Users, which has the following schema:

Implementing OTP in PHP using Twilio Database

This schema for the users table is self-explanatory and a very simplistic one.

Code Base and Steps to Run

  • GitHub Repo: Project repository
  • Just clone it and run composer install after moving into the project's directory.
  • The composer will automatically (after reading the composer.json file) import the necessary Twilio SDK.
  • You just need to set up your virtual host and you are good to go.

If you have any questions, write them in comments so that we can discuss it further. 

Thanks!

Topics:
otp token ,twilio ,php tutorial ,web dev ,web application security

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}