To recover the forgotten password using PHP and MySQL

Prerequisite: Basic Understanding of HTML, CSS, PHP and MySQL.

In this project:

  • We will create a simple HTML Form to take user’s registered ID as input.           
  • If entered email is correct, a temporary key is generated and is stored in a password_reset table along with its expiry date i.e. after 24 hours.                     
  • User is emailed a link to reset the forgotten password.                                          
  • When users clicks that link, the user is directed to the password reset page, where the user can enter new password and clicks RESET PASSWORD button.                                                                                                                          
  • The error or success messages are displayed accordingly.

index.php ⬇

<?php
    include_once 'includes/conn.php';
    if(isset($_POST['email']) && $_POST['email'] != ""){
        $error_message = "";
        $email = $_POST['email'];
        $email = filter_var($email, FILTER_SANITIZE_EMAIL);
        $email = filter_var($email, FILTER_VALIDATE_EMAIL);
        if($email != ""){
            $sql = "SELECT * FROM users WHERE email = '".$email."' AND status = '1'";
            $result = mysqli_query($con, $sql);
            $row = mysqli_num_rows($result);
            if($row == 0){
                $error_message = "No user exists with this email ID.";
            }
        }else{
            $error_message = "Please Enter valid email ID.";
        } 
        if($error_message == ""){
            $expireDate = date('Y-m-d H:i:s', strtotime(date('Y-m-d H:i:s') . ' +1 day'));
            $temp_pass = md5("1222390".$email);
            $sql = "INSERT INTO password_reset(`id`, `email`, `temp_pass`, `expired_at`) 
                            VALUES('', '".$email."', '".$temp_pass."', '".$expireDate."')";
            mysqli_query($con, $sql);
            
            $subject = "Password Recovery";
            $to = $email;
            $from = "[email protected]";
            
            $headers  = 'MIME-Version: 1.0' . "\r\n";
            $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
            $headers .= 'From: '.$from."\r\n".
                        'Reply-To: '.$from."\r\n" .
                        'X-Mailer: PHP/' . phpversion();
            
            $message = '<p>Dear User,</p>';
            $message .= '<p>Please click the following link to reset your password.</p>';
            $message .= '<hr>';
            $message .= '<p><a href="http://localhost/projects/forgot_password/reset_password.php?key='.$temp_pass.'&email='.$email.'&action=reset" target="_blank">
            http://localhost/projects/forgot_password/reset_password.php?key='.$temp_pass.'&email='.$email.'&action=reset</a></p>';		
            $message .= '<hr>';
            $message .= '<p>Above link will expire after 1 day.</p>';
            if(!mail($to, $subject, $message, $headers)){
                echo "<div class='success'>
                        <p>An email has been sent to your registered email ID to reset your password.</p>
                      </div>";
            } else{
                echo "<div class='error'>
                        <p>Error in sending mail.</p>
                      </div>";
            }            
        }else{
            echo "<div class='container'>
                    <div class='col-md-6'>
                        <div class='error'>".$error_message."</div>
                        <a href='javascript:history.go(-1)'>Go Back</a>
                    </div>
                  </div>
                  <hr>";
            die();
        }   
    } // .main If
?>
<html>
    <head>
        <title>Forgot Password</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
        <style>
            .error{color: red; padding: 10px 0;}
        </style>
    </head>
    <body>
        <div class="container">
            <h4>Forgot Password ?</h4>
            <form method="POST" action="index.php">
                <div class="row">
                    <div class="col-md-4">
                        <label>Enter Email: </label>
                        <input type="email" name="email" class="form-control">
                    </div>
                </div>
                <br>
                <button type="submit" value="" class="btn btn-primary" name="forgot_password_btn">SEND LINK</button>        
            </form>
        </div>
    </body>
</html>
  • HTML Form is created with an Email textbox and a SEND LINK button.
<form method="POST" action="index.php">
   <input type="email" name="email" class="form-control">     
   <button type="submit" value="" name="forgot_password_btn">SEND LINK</button>        
</form>
  • Form is posted to the same page and values are filtered and validated using PHP functions.  
if(isset($_POST['email']) && $_POST['email'] != ""){
   $error_message = "";
   $email = $_POST['email'];
   $email = filter_var($email, FILTER_SANITIZE_EMAIL);
   $email = filter_var($email, FILTER_VALIDATE_EMAIL);
}
  • If the value is properly validated and is not empty, user record is fetched with that corresponding email ID and in case of error, the variable is assigned an error message.
if($email != ""){
   $sql = "SELECT * FROM users WHERE email = '".$email."' AND status = '1'";
   $result = mysqli_query($con, $sql);
   $row = mysqli_num_rows($result);
   if($row == 0){
        $error_message = "No user exists with this email ID.";
   }
}else{
     $error_message = "Please Enter valid email ID.";
} 
  • In case of no error,  a required link to reset password file is generated and is emailed to the user. If mail sending is successful, Success message is displayed. Otherwise, error message is displayed to the user.
if($error_message == ""){
   $expireDate = date('Y-m-d H:i:s', strtotime(date('Y-m-d H:i:s') . ' +1 day'));
   $temp_pass = md5("1222390".$email);
   $sql = "INSERT INTO password_reset(`id`, `email`, `temp_pass`, `expired_at`) 
                  VALUES('', '".$email."', '".$temp_pass."', '".$expireDate."')";
   mysqli_query($con, $sql);
   $subject = "Password Recovery";
   $to = $email;
   $from = "[email protected]";
   $headers = "Headers Content…";            
   $message = "Message Body to be emailed…";
   if(!mail($to, $subject, $message, $headers)){
      echo " An email has been sent to your email ID to reset your password.";
   }else{
      echo "Error in sending mail.";
   }
}      

        


  • A key is generated using md5 method and its expiry date is also inserted in “password_reset” table which is further used while resetting the password. 

Reset_password.php

<?php
    include_once 'includes/conn.php';
    $action = (isset($_GET['action']) && $_GET['action'] == 'reset') ? $_GET['action'] : "";
    $key = (isset($_GET['key']) && $_GET['key'] != '') ? $_GET['key'] : "";
    $email = $_GET['email'];
    $email = filter_var($email, FILTER_SANITIZE_EMAIL);
    $email = filter_var($email, FILTER_VALIDATE_EMAIL);
    $message = "";
    if($action != "" && $key != "" && $email != ""){
        $current_date = date('Y-m-d H:i:s');
        $sql = "SELECT * FROM password_reset 
                        WHERE email = '".$email."' AND temp_pass = '".$key."' AND expired_at >= '".$current_date."'";
        $exe = mysqli_query($con, $sql);
        $result = mysqli_num_rows($exe);
        if($result > 0){
?>
            <html>
                <head>
                    <title>RESET YOUR PAASWORD</title>
                    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
                </head>
                <body>
                    <div class="container" style="margin-top:20px">
                        <form method="POST" action="reset_process.php">
                            <div class="row">
                                <div class="col-md-4">
                                    <label>Enter New Password: </label>
                                    <input type="password" name="new_pass" class="form-control">
                                </div>
                            </div>
                            <br>
                            <div class="row">
                                <div class="col-md-4">
                                    <label>Re-enter New Password: </label>
                                    <input type="password" name="re_new_pass" class="form-control">
                                </div>
                            </div>
                            <input type="hidden" name="action" value="update">
                            <input type="hidden" name="email" value="<?=$email?>">
                            <br>
                            <button type="submit" value="" class="btn btn-primary" name="reset_password_btn">RESET PASSWORD</button>        
                        </form>
                    </div>
                </body>
            </html>
<?php   }else{
            $message = "<h4>INVALID LINK</h4>
                        <p>Either the link is not correct or the key has been already used by you, therefore it is deactivated.</p>
                        <p>Thank You.</p>";
        }
    }else{
        $message = "Error";
    }
    if(isset($message) && $message != ""){
        echo "<div class='error'>".$message."</div>";
    }
?>
  • If action, key and email variables are set and are properly validated. Key expiry is checked. If the key is not expired, Reset form is displayed. Otherwise, the error message is displayed on the screen.
if($action != "" && $key != "" && $email != ""){
   $current_date = date('Y-m-d H:i:s');
   $sql = "SELECT * FROM password_reset WHERE email='".$email."' AND
                temp_pass='".$key."' AND expired_at >= '".$current_date."'";
   $exe = mysqli_query($con, $sql);
   $result = mysqli_num_rows($exe);
   if($result > 0){
       // RESET FORM
   }else{
            $message = "<h4>INVALID LINK</h4>";
   }
}
  • A Reset form is created with textfields for New Password and Re-enter New Password. Hidden field for user’s email ID is also created for further processing.
<form method="POST" action="reset_process.php">
     <input type="password" name="new_pass" class="form-control">
     <input type="password" name="re_new_pass" class="form-control">
     <input type="hidden" name="email" value="<?=$email?>">
     <button type="submit" value="" name="reset_password_btn">RESET PASSWORD</button>        
</form>

The form is posted to the reset_process.php file which is explained below.

Reset_process.php

<?php
    include_once 'includes/conn.php';
    if(isset($_POST['action']) && $_POST['action'] == "update"){
        $pass = trim($_POST['new_pass']);
        $re_pass = trim($_POST['re_new_pass']);
        $email = $_POST['email'];
        $email = filter_var($email, FILTER_SANITIZE_EMAIL);
        $email = filter_var($email, FILTER_VALIDATE_EMAIL);
        if($pass != "" && $re_pass != ""){
            if($pass === $re_pass){
                $sql = "UPDATE users SET password = '".$pass."' WHERE email = '".$email."' LIMIT 1";
                mysqli_query($con, $sql);
                $sql = "DELETE FROM password_reset WHERE email = '".$email."'";
                mysqli_query($con, $sql);
                $message = "<p>Congratulations! Your password has been updated successfully.</p>";
            }else{
                $message = "<p>Both Passwords do not match.</p>";
            }
        }else{
            $message = "<p>Please fill both values properly.</p>";
        }
        if(isset($message) && $message != ""){
            echo $message;
        }
    }
?>
  • Posted values are filtered and validated using PHP functions. Password and Re-enter Password values are matched. If both values do not match, error message is echoed to the screen.                                                                             
  • Otherwise, users table is updated with the newly entered password value.        
  • Key value from the password_reset table is deleted to deactivate the link.

Summary

In this project, we have learned to recover the forgotten password of our registered email Id on a website. There can be various ways to recover the password, one can implement any of them as per the requirement of their website. However, we have simply emailed the link to the user to reset the password, where user can create a new password of his/her own choice and afterwards the link is deactivated by deleting the key generated for this particular process for a user’s ID.

Help Us to Improve our content

Let's Talk
Go back to Previous Course