Forgot Password and password reset form in PHP with MYSQL


Every time most people forget their password and try to reset the password on the website.

We are creating registration and login form in PHP from the scratch. In this tutorial, we will create a forgot password form and reset the password form in PHP with MYSQL.

In the previous tutorial, we created a registration and login system in PHP and also we created a forgot password link on the login page.

In this tutorial, we will create a forgot password system in PHP

Forgot Password form in PHP with MYSQL –

The forgot password form is used to update the user password using the link on the email.

In the forgot password form, the user enters a username or email to find his account and clicks on the send link button. The password reset link goes to the user's email and the user clicks on the link. The user redirects to the password reset page and updates his password.

In this forgot password system, we will create two forms. First to find out the user and second for a password reset.

Create a database table –

In the previous tutorial, we had created a user table, and now will create a password reset table.


CREATE TABLE `pass_reset` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(255) NOT NULL,
  `token` varchar(255) NOT NULL, 
   PRIMARY KEY (`id`)
);

Execute the query above in your PHPMYADMIN panel.

In this table above, we have created two fields. We will insert an email and token in the password reset table after finding the account. We will send a password reset link with a password reset form page and token.

The token will be a random id. We will find an email with token and update by email id. This is really easy.

Create a forgot password form -

In the previous tutorial, we used bootstrap to design responsive forms and also created an extra CSS file in the previous tutorial.

Let's create a forgot password form –

Create a file with the name – forgot-password.php

forgot-password.php

<!DOCTYPE html>
<?php require_once("config.php");
if(isset($_SESSION["login_sess"])) 
{
  header("location:account.php"); 
}
?>
<html>
<head>
<title> Forgot Password - Techno Smarter</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"> 
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
	<div class="row">
		<div class="col-sm-4">
		</div>
		<div class="col-sm-4">
 	<form action="forgot_process.php" method="POST">
    <div class="login_form">
  <div class="form-group">
 <img src="https://technosmarter.com/assets/images/logo.png" alt="Techno Smarter" class="img-fluid logo"> 
 <?php if(isset($_GET['err'])){
 $err=$_GET['err'];
 echo '<p class="errmsg">No user found. </p>';
} 
// If server error 
if(isset($_GET['servererr'])){ 
echo "<p class='errmsg'>The server failed to send the message. Please try again later.</p>";
   }
   //if other issues 
   if(isset($_GET['somethingwrong'])){ 
 echo '<p class="errmsg">Something went wrong.  </p>';
   }
// If Success | Link sent 
if(isset($_GET['sent'])){
echo "<div class='successmsg'>Reset link has been sent to your registered email id . Kindly check your email. It can be taken 2 to 3 minutes to deliver on your email id . </div>"; 
  }
  ?>
  <?php if(!isset($_GET['sent'])){ ?>
    <label class="label_txt">Username or Email </label>
    <input type="text" name="login_var" value="<?php if(!empty($err)){ echo  $err; } ?>" class="form-control" required="">
  </div>
  <button type="submit" name="subforgot" class="btn btn-primary btn-group-lg form_btn">Send Link </button>
  <?php } ?>
</div>
</form>
   <br> 
   <p>Have an account? <a href="login.php">Login</a> </p>
    <p>Don't have an account? <a href="signup.php">Sign up</a> </p> 
		</div>
		<div class="col-sm-4">
		</div>
	</div>
</div> 
</body>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js"></script>
</html>

In the code above, we have created one field to find out the user account.

Forgot password form in PHP and MYSQL

Now, we will create a forgot password process file.

Create PHP scripts for forgot password form –

In this PHP file, we will follow the steps –

  1. Find the user account with the entered value. If the user account exits or not in our system database.
  2. If the user found then fetch the email and insert it into the pass_reset data table with token id.

The token id will be generated with and random_bytes() PHP function .


$token = bin2hex(random_bytes(50));
  1. Insert email and token id pass_reset table.
  2. Now, we will use the PHP mail() function to send an email on the user email id
  3. In the message of mail()function, we will send some text with password reset form and token id link.
$msg="Your password reset link <br> http://technosmarter.com/php/form/password-reset.php?token=".$token." <br> Reset your password with this link .Click or open in new tab<br><br> <br> <br> <center>".$credits."</center>"; 

The user will receive the link to the password reset form page and click on it.

Create a file with the name –   forgot_process.php

forgot_process.php

<?php 
 require_once("config.php");
if(isset($_POST['subforgot'])){ 
$login=$_REQUEST['login_var'];
$query = "SELECT * from  users where (username='$login' OR email = '$login')"; 
$res = mysqli_query($dbc,$query);
$count=mysqli_num_rows($res);
//echo $count;
if($count==1)
{
$findresult = mysqli_query($dbc, "SELECT * FROM users WHERE (username='$login' OR email = '$login')");
if($res = mysqli_fetch_array($findresult))
{
$oldftemail = $res['email'];  
}
$token = bin2hex(random_bytes(50));
 $inresult = mysqli_query($dbc,"insert into pass_reset values('','$oldftemail','$token')"); 
 if ($inresult)  
 { 
$FromName="Techno Smarter";
$FromEmail="no_reply@technosmarter.com";
$ReplyTo="technosmarterinfo@gmail.com";
$credits="All rights are reserved | Techno Smarter "; 
$headers  = "MIME-Version: 1.0\n";
     $headers .= "Content-type: text/html; charset=iso-8859-1\n";
     $headers .= "From: ".$FromName." <".$FromEmail.">\n";
      $headers .= "Reply-To: ".$ReplyTo."\n";
      $headers .= "X-Sender: <".$FromEmail.">\n";
       $headers .= "X-Mailer: PHP\n"; 
       $headers .= "X-Priority: 1\n"; 
       $headers .= "Return-Path: <".$FromEmail.">\n"; 
         $subject="You have received password reset email"; 
     $msg="Your password reset link <br> http://localhost:8081/php/form/password-reset.php?token=".$token." <br> Reset your password with this link .Click or open in new tab<br><br> <br> <br> <center>".$credits."</center>"; 
   if(@mail($oldftemail, $subject, $msg, $headers,'-f'.$FromEmail) ){
header("location:forgot-password.php?sent=1"); 
$hide='1';
          
    } else {
        
    header("location:forgot-password.php?servererr=1"); 
} 
      } 
      else 
      { 
          header("location:forgot-password.php?something_wrong=1"); 
      }     
}
else  
{
header("location:forgot-password.php?err=".$login); 
}
}
?>

You can understand the code by the points above.

Let’s create a password reset form –

Password reset form in PHP with MYSQL –

The password reset form comes after clicking on the link. It’s used to update passwords. This is another form like the registration form. We remove all other fields and only leave the password and confirm the password in the form.

We get the value of the token and find the email that relates to the token. If the email has found then we will use that email to reset the password in the user's table. The remaining process will be the same as the update operation in PHP . Convert password simple text to hash pattern and update using an update query.

Create a file with the name – password-reset.php

password-reset.php

<!DOCTYPE html>
<?php require_once("config.php");
if(isset($_SESSION["login_sess"])) 
{
  header("location:account.php"); 
}
?>
<html>
<head>
<title> Password Reset - Techno Smarter</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"> 
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
	<div class="row">
		 <div class="col-sm-4">
		</div>
		<div class="col-sm-4">
      <?php
            if(isset($_GET['token']))
            {
          $token= $_GET['token'];
          }
   //form for submit 
    if(isset($_POST['sub_set'])){
       extract($_POST);
            if($password ==''){
                $error[] = 'Please enter the password.';
            }
            if($passwordConfirm ==''){
                $error[] = 'Please confirm the password.';
            }
            if($password != $passwordConfirm){
                $error[] = 'Passwords do not match.';
            }
            if(strlen($password)<5){ // min 
            $error[] = 'The password is 6 characters long.';
        }
         if(strlen($password)>50){ // Max 
            $error[] = 'Password: Max length 50 Characters Not allowed';
        }
        $fetchresultok = mysqli_query($dbc, "SELECT email FROM pass_reset WHERE token='$token'");
    if($res = mysqli_fetch_array($fetchresultok))
{
  $email= $res['email']; 
}
            if(isset($email) != '' ) {
            $emailtok=$email;
            }
            else 
              { 
             $error[] = 'Link has been expired or something missing ';
              $hide=1;
              }
if(!isset($error)){
    $options = array("cost"=>4);
    $password = password_hash($password,PASSWORD_BCRYPT,$options);
    $resultresetpass= mysqli_query($dbc, "UPDATE users SET password='$password' WHERE email='$emailtok'"); 
    if($resultresetpass) 
    { 
           $success="<div class='successmsg'><span style='font-size:100px;'>&#9989;</span> <br> Your password has been updated successfully.. <br> <a href='login.php' style='color:#fff;'>Login here... </a> </div>";

          $resultdel = mysqli_query($dbc, "DELETE FROM pass_reset WHERE token='$token'");
          $hide=1;
    }
} 
    }
    ?>
    <div class="login_form">
		<form action="" method="POST">
  <div class="form-group">
    <img src="https://technosmarter.com/assets/images/logo.png" alt="Techno Smarter" class="logo img-fluid"> 
    <?php 
if(isset($error)){
        foreach($error as $error){
            echo '<div class="errmsg">'.$error.'</div><br>';
        }
    }
    if(isset($success)){
    echo $success;
  }
              ?>
<?php if(!isset($hide)){ ?>
    <label class="label_txt">Password </label>
      <input type="password" name="password" class="form-control" required>
  </div>
   <div class="form-group">
    <label class="label_txt">Confirm Password </label>
      <input type="password" name="passwordConfirm" class="form-control" required  >
  </div>
  <button type="submit" name="sub_set" class="btn btn-primary btn-group-lg form_btn">Reset Password</button>
  <?php } ?>
</form>
</div>
		</div>
		<div class="col-sm-4">
		</div>
	</div>
</div> 
</body>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js"></script>
</html>
Forget password in PHP

In the PHP code above, you can see, we used the delete operation after updating the password. This is really important that we delete tokens from the pass_reset table after updating the password.

In this way, you can create a forgotten password system or you can say forgot password form link for the login form on the PHP website.


Please Share

Recommended Posts:-

Previous Posts:-

Featured Items:-


Ecommerce system in PHP website | Digital Ecommerce Shop web app

$66



Paypal payment form with email, invoice generator in PHP website | Scripts

$39



Certificate system in PHP website | PHP scripts

$22





11 Comments
Seow Hong Shyang 20 Apr 2023

When I press send link. It shows "The server failed to send the message. Please try again later." What happens in this situation?

@Seow Hong Shyang replied by Techno Smarter 20 Apr 2023

There are many reasons for this error - 

1. You are testing on the local server. Test it on the live server. 

2. Maybe incorrect from email ($FromEmail) value . Kindly set your website official email like info@yourwebsite.com or noreply@yourwebsite.com

3. Cheap hosting - Maybe your hosting does not support default mail or the mail feature is disabled. You should contact your hosting provider. 

These are the main reasons. 

Mark 28 Mar 2023

Hi, there I'm testing this on a live server and it's not working correctly. I have the user in my database, searching for email. the user has the correct email. It keeps showing the error "No User Found". I've checked the connection script and it's correct, works with all other PHP scripts.

@Mark replied by Techno Smarter 28 Mar 2023

First of all, check your username and email in the database. The table id should be auto increment. Now, we have updated the forget_process.php file code to count user row in the users table. Maybe you have an issue with your query.  

$query = "SELECT * from  users where (username='$login' OR email = '$login')"; 

Kindly write the exact table name and fields name. You can comment on the line in the forget_process.php file to see the exact error in the forget_process.php file.

//header("location:forgot-password.php?err=".$login); 

After fixing the issue, kindly uncomment the above code line.

@Techno Smarter replied by Mark 30 Mar 2023

That's fantastic, finally got it working. Thank you. I notice that you are using BCRYPT to hash the new password. How do I go about setting the password value to SHA256 as my users are registering and storing their password in SHA256 format?

@Mark replied by Techno Smarter 30 Mar 2023

Try like this - 

$password='mypass';
$hashedPassword = hash('sha256', $password);

sha256 => 64 bits  , sha384 => 96 bits , sha512 => 128 bits

@Techno Smarter replied by Mark 30 Mar 2023

You are a star. Thank you so much. Greatly appreciated.

vijayendra kumbhar 01 Mar 2023

Not working forgot password.

@vijayendra kumbhar replied by Techno Smarter 02 Mar 2023

Are you testing on localhost? Kindly test on the live server or elaborate more about your issues.

@Techno Smarter replied by vijayendra kumbhar 02 Mar 2023

No i test it on live server, after click on send link showing this error "https://resumeboost.io/old-2/forgot-password.php?something_wrong=1", otherwise all are working except this one.

@vijayendra kumbhar replied by Techno Smarter 03 Mar 2023

It means you are getting false from your query. There is an error in your insert query in the file forgot_process.php. 

$inresult = mysqli_query($dbc,"insert into pass_reset values('','$oldftemail','$token')");

Kindly check your columns, table name, or query. 

or you can write query like this - 

$inresult = mysqli_query($dbc,"INSERT INTO pass_reset(email,token) VALUES('$oldftemail','$token')");