Friday, 15 March 2019

Implementing OTP in PHP using Twilio

Verifying a phone number using OTP (One Time Password) is a sure shot way to reduce the spam over your website. In this article, we will be going to discuss this topic in great detail. We will be learning how we can set up our PHP code to send the OTP to the mobile numbers and hence verifying the user.

We would be using Twilio as a third party service to send the messages containing One Time Passwords (OTPs). After going through this article, you would be able to integrate the OTP feature in your PHP project as it deals in great depth with the detailed procedure of sending OTP in PHP.




Prerequisites:

Suggested Read: Redis vs MySQL Benchmarks


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 would 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 it would suffice for our article and hence our purpose. 

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 know more about the Free Trial Account on Twilio visit this.
  • Once you complete the SignUp process, Proceed to 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 "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 would be sending text messages on your behalf.
  • Now, as your account is Trial, 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:

Our complete workflow would be (You are obviously free to modify this as per your requirements):
  • The person would be asked to enter the country code and mobile number. Please note that, as you are using 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.
  • It the mobile number is already present in our database and it has already been verified (which we would check from "is_verified" flag from 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 from "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 would also save the OTP sent in our database. As a side note, we would be generating a random 4 digit number as OTP using simple PHP rand() function.
Sample OTP Received

  • After the user has received, the user can enter the OTP received on his/her mobile number and click verify.
Implementing OTP in PHP using Twilio

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

Actual Code:

We would be having 5 files:
  • index.php
<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.

CodeBase and steps to run:

  • GitHub Repo: Project repository
  • Just Clone it and run "composer install" after moving into the project's directory.
  • The composer would automagically (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.

Liked this blog? Don't miss out on any future blog posts by Subscribing Here or you can also like our Facebook Page or follow us on Twitter

1 comment: