Hello there, Today, I'll teach you how to use PHP to perform OTP verification, which involves logging in with an OTP. OTP authentication is the safest way to log in to the dashboard, which is something that many users do.
This can be achieved using a mobile-based OTP system; however, you will need to buy Bulk SMS Service from an SMS Service Provider, which will cost you money. You can also use a free email-based OTP system to send your OTP to your users for login.
In this tutorial, you'll learn how to dynamically generate OTP and send it to a registered user's email address when they try to log in.
The user enters the OTP number in the verification form after receiving it. If the user's credentials match, the user is authenticated and redirected to the dashboard; if the user's credentials do not match, an incorrect OTP error message is displayed.
What is OTP Verification?
While registration and login, OTP Verification authenticates users' Email Account or Phone Number by delivering an OTP verification code. It eliminates the risk of a user registering using a fictitious email address or mobile number.
What is OTP email?
You may use the Email OTP protocol to authenticate by sending a one-time password (OTP) to the registered email id. If you attempt to log in on any device like laptop, PC, mobile, the server transfers an email with the OTP to the registered email id.
Project Directory Structure
The project directory structure is stored in the C:\xampp\htdoc, as shown below. Since the XAMPP server is installed on the C drive.
Note: Install this project in the www folder if you're using the WAMP server.
xampp/
├── htdocs/
├── OTP-Verification-In-PHP/
├── bootstrap/
├── css/
│ └── bootstrap.min.js
├── js/
│ └── bootstrap.min.js
├── fonts/
│ └── glyphicons-halflings-regular.eot
│ └── glyphicons-halflings-regular.svg
│ └── glyphicons-halflings-regular.ttf
│ └── glyphicons-halflings-regular.woff
│ └── glyphicons-halflings-regular.woff2
├── js/
│ └── jquery-1.12.4-jquery.min.js
├── smtp
check_otp.php
dbconfig.php
index.php
logout.php
send_otp.php
welcome.php
Database and Table
First, build a database in PhpMyAdmin with whatever name you want. To build a user table with email and OTP fields, import the SQL code below.
Here,
I've already inserted one dumping record. We'll say that this email address was used by test named user once he signed up for our website. Since this project requires the user's existing registration on the system.
CREATE TABLE IF NOT EXISTS `tbl_user` (
`id` int(11) NOT NULL,
`email` varchar(30) NOT NULL,
`otp` varchar(10) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `tbl_user`
--
INSERT INTO `tbl_user` (`id`, `email`, `otp`) VALUES
(1, '[email protected]', '');
dbconfig.php
This file contains the code for creating a connection with the MySQLi extension.
<?php
$DBhost = "localhost";
$DBuser = "root";
$DBpassword ="";
$DBname="otp_varification_db";
$connection = mysqli_connect($DBhost, $DBuser, $DBpassword, $DBname);
if(!$connection){
die("Connection failed: " . mysqli_connect_error());
}
?>
index.php
This file displays a form in HTML pretty. As you can see, I have two division tags inside this form.
The first division tag will use the user's email to identify their account, while the second division tag will validate the OTP number entered by the user.
The $.ajax() method was used to send both divisions' requests.
<form method="post" class="form-horizontal">
<h3 class="text-center">Log in</h3>
<!-- first division start -->
<div class="form-group first_division">
<label class="col-sm-3 control-label">Enter Email</label>
<div class="col-sm-6">
<input type="text" id="txt_email" class="form-control" placeholder="enter email" />
</div>
</div>
<div class="form-group first_division">
<div class="col-sm-offset-3 col-sm-6 m-t-15">
<button type="button" id="btn_send" class="btn btn-success btn-block">Send OTP</button>
</div>
</div>
<center>
<span class="text-danger" id="email_error" style="font-size:20px;"></span>
<span class="text-success" id="success_msg" style="font-size:20px;"></span>
</center>
<!-- first division end -->
<!-- second division start -->
<div class="form-group second_division">
<label class="col-sm-3 control-label">Enter OTP</label>
<div class="col-sm-6">
<input type="text" id="txt_otp" class="form-control" placeholder="enter otp" />
</div>
</div>
<div class="form-group second_division">
<div class="col-sm-offset-3 col-sm-6 m-t-15">
<button type="button" id="btn_submit" class="btn btn-warning btn-block">Submit OTP</button>
</div>
</div>
<center>
<span id="otp_error" class="text-danger" style="font-size:20px;"></span>
</center>
<!-- second division end -->
</form>
Here,
By default, I hide the second division tag with the CSS codes below, which I place before the closing </head> tag.
The second division will be shown by the $.ajax() method if the user enters an email address that has been checked by the server.
<style type="text/css">
.second_division
{
display:none;
}
</style>
Okay, For OTP generation, sends an ajax request to the server.
Ajax Code
The code in JavaScript/jQuery is in command of quietly executing all of the operations.
The click() method causes and activates the event button when the user clicks the send OTP button. The #btn_send id attribute of the button.
#txt_email is the id attribute of the email text box using that attribute the .val() method to get the email value.
If no validation is conducted, the $.ajax() function is called. This function is the responsibility of submitting a request to the server's "send_otp.php" file to generate an OTP.
The success function will hide the first division tag and display the second division tag with the appropriate message inside the #success_msg span tag if the response is "send."
If the response involves the string "wrong_email" the required message will be displayed inside the #email_error span tag
The trim() method removes whitespace from both sides of a string. ( note take from PHP w3schools )
Note: The trim() method does not change the original string. ( note take from PHP w3schools )
$(document).ready(function(){
$(document).on("click", "#btn_send", function(e){
var email = $("#txt_email").val();
var atpos = email.indexOf("@");
var dotpos = email.lastIndexOf(".com");
if(email == ""){
alert("Please Enter Email Address");
}
else if(atpos < 1 || dotpos < atpos + 2 || dotpos + 2 >= email.length){
alert("Please Enter Valid Email Address !");
}
else{
$.ajax({
url: "send_otp.php",
type: "post",
data: {uemail:email},
success:function(response){
if($.trim(response)=="send"){
$("#email_error").remove();
$("#success_msg").html("otp send check your mail box... and enter it here");
$(".second_division").show();
$(".first_division").hide();
}
if($.trim(response)=="wrong_email"){
$("#email_error").html("sorry, you enter wrong email");
}
}
});
}
});
});
The server will deliver an OTP to the email address.
send_otp.php
This file will operate quietly at the back-end and call through $.ajax() method using jQuery code, containing only PHP code to verify users' registered email in the user table.
If the email address is found in the table, a random OTP number will be generated and sent to the user's registered email address.
To send emails using Gmail SMTP, I used PHPMailer, which you can use on your localhost server.
<?php
session_start();
require_once "dbconfig.php";
if(isset($_POST['uemail']))
{
$email=$_POST['uemail'];
$result=mysqli_query($connection,"SELECT * FROM tbl_user WHERE email='".$email."' ");
$count=mysqli_num_rows($result);
if($count > 0)
{
$otp=rand(11111,99999); //generate otp randomly
mysqli_query($connection,"UPDATE tbl_user SET otp='".$otp."' WHERE email='".$email."' ");
$otp_code = "Your otp verification code is ".$otp;
$_SESSION["USER_EMAIL"]=$email; //set current user email in $_SESSION[] method
require_once('smtp/PHPMailerAutoload.php');
$mail=new PHPMailer(true);
$mail->isSMTP();
$mail->Host="smtp.gmail.com";
$mail->Port=587;
$mail->SMTPSecure="tls";
$mail->SMTPAuth=true;
$mail->Username=""; //Enter your gmail id
$mail->Password=""; //Enter your gmail id password
$mail->SetFrom(""); //Enter your gmail id
$mail->addAddress($email); //paste user email
$mail->IsHTML(true);
$mail->Subject="OTP Verification";
$mail->Body = ($otp_code);
$mail->SMTPOptions=array('ssl'=>array(
'verify_peer'=>false,
'verify_peer_name'=>false,
'allow_self_signed'=>false
));
if($mail->send())
{
echo "send";
}
else
{
echo "Mailer Error" . $mail->ErrorInfo;
}
}
else
{
echo "wrong_email";
}
}
?>
Codes Explanation:
how to generate OTP,
Row no 16 – As you can see, we used the rand() function to generate a random integer OTP number, which we saved in the $otp variable.
Row no 18 – use the mysqli_query() function to execute an update query, and save or set the created new OTP number to his or her email address in the table.
Row no 20 – see create simple OTP verification HTML template. Users receive this message in their inbox, as seen in the figure below.
Row no 22 – We store or keep current user email for identification using the $_SESSION[ ] method. The session name "USER_EMAIL" contains the current user's email address.
Now,
If an email was found in the database table, it will be shown below the second division.
The division tag contains a simple text box where users can enter their OTP verification code. The $.ajax() method is used to send the division tag request to the server.
<!-- second division start -->
<div class="form-group second_division">
<label class="col-sm-3 control-label">Enter OTP</label>
<div class="col-sm-6">
<input type="text" id="txt_otp" class="form-control" placeholder="enter otp" />
</div>
</div>
<div class="form-group second_division">
<div class="col-sm-offset-3 col-sm-6 m-t-15">
<button type="button" id="btn_submit" class="btn btn-warning btn-block">Submit OTP</button>
</div>
</div>
<center>
<span id="otp_error" class="text-danger" style="font-size:20px;"></span>
</center>
<!-- second division end -->
Ajax Codes
After completing the send OTP ajax step, add the following ajax codes to the index.php file.
When the user presses the submit button after entering the OTP, the $.ajax() function is called. This function sends the OTP request from the user to the server's "check_otp.php" file, which verifies the OTP.
If the server response message is "valid" the user will be redirected to the "welcome.php" file. If the server response is "invalid" the #otp_error span tag will show the appropriate message.
Other Guides,
If the user clicks on the submit OTP button, the click() method causes and triggers the event button. The #btn_submit id attribute of button.
#txt_otp is id attribute of the OTP text box using that attribute the .val() method to get the OTP value.
$(document).on("click", "#btn_submit", function(e){
var otp=$("#txt_otp").val();
$.ajax({
url:"check_otp.php",
type:"post",
data: {uotp:otp},
success:function(response){
if($.trim(response)==="valid"){
window.location="welcome.php"
}
if($.trim(response)==="invalid"){
$("#otp_error").html("sorry, you enter invalid otp number");
}
}
});
});
check_otp.php
This PHP file uses the $.ajax() method to communicate with the backend and check the user's submission of the OTP number from the table. Send the response "valid" if it's present, and "invalid" if it's not.
Row no 10 – We get the current user email who entered the OTP number using the $_SESSION[ ] method.
Row no 12 – Use the mysqli_query() function to run a SQL select query and verify the OTP number of the current user's email address in the table.
If an OTP is found in the table, run a SQL update query to erase the OTP number.
Row no 20 – The current user's email address is saved in the $_SESSION[] method of the user who entered the OTP code. The “USER_LOGIN” is the session name.
<?php
session_start();
require_once "dbconfig.php";
if(isset($_POST["uotp"]))
{
$otp = $_POST["uotp"];
$email = $_SESSION["USER_EMAIL"];
$result=mysqli_query($connection,"SELECT * FROM tbl_user WHERE email='".$email."' and otp='".$otp."' ");
$count=mysqli_num_rows($result);
if($count > 0)
{
mysqli_query($connection,"UPDATE tbl_user SET otp='' WHERE email='".$email."' ");
$_SESSION["USER_LOGIN"]=$email;
echo "valid";
}
else
{
echo "invalid";
}
}
?>
welcome.php
The $_SESSION[ ] superglobal array method is used to locate a “USER_LOGIN” session object. If the header () function fails to find the page, it redirects to the index page. Without the session, the unauthorized user is unable to access the welcome page.
<div class="wrapper">
<div class="container">
<div class="col-lg-12">
<center>
<h2>
<?php
session_start();
if(isset($_SESSION["USER_LOGIN"]))
{
echo "Hi, welcome dashboard";
}
else
{
header("location:index.php");
die();
}
?>
</h2>
<h3><a href="logout.php">Logout</a></h3>
</center>
</div>
</div>
</div>
logout.php
We destroy the session from the welcome page, as well as the logout hyperlink, in this file, and submit everything to the index.php / login page.
<?php
session_start();
header("location:index.php");
session_destroy();
?>
Learn More:
What does array splice do in PHP
What is POST variable in PHP
What is Custom PHP Development
How do you append to text in PHP
How to store textarea value in database in PHP
How to Fetch Data from Database in JSON format in PHP
How to get the class name in PHP
How to Run PHP Code in Browser
How to Check if a String is Null in PHP
How to Pass Dropdown Selected Value to Database in PHP
How to Create Drop Down List in PHP with MySQL
How to Process a Form using PHP
Download Codes
Thanks for sharing. I have issue with this code is when send otp i create otp in DB and send email but it did not prompt any message like please check email etc. And not otp submit button section2 displayed for entering otp.
ReplyDeletethe code work perfectly please download source code and try again
DeleteThank for reply the AJAX code in index.php is not working. I downloaded and tried as you said. there is some issue Ajax response code.
ReplyDeleteHi, asad I checked the code perfectly work on my localhost server.
DeleteHello, thank you so much for this code. I too seem to have a problem. When I enter the email address and click on the "Send otp" button I receive the 5 digit numeric otp via email, but the form does not advance to show the second division where one is suppose to enter the OTP number and thus submit it. Could there be something wrong with my jQuery ajax script? FYI I'm using Wamp. Any suggestions would be appreciated. Thank you.
ReplyDeleteNo matter you are using WAMP server. The source code work perfectly. Please follow codes instruction otherwise download source code zip file
Delete