LIVE DEMODOWNLOAD

Recently I have cover few topics on user authentication like PHP Login System, Register new user and Email verification when new user register on site. So here I am going to deal with “Forgot Password Utility” that most of websites have. There are some people exist on this world who always forget their password. For those mates we should have “forgot password utility” on our website. This is very useful feature. And I am sure after reading this article you will be able to add this functionality your website.

I am sure you have already user authentication system on your website, that’s why you are reading this article. If not yet, then read my following articles that cover user authentication system.

  1. PHP Login Script with Session
  2. Creating Registration Form with PHP and MySQLi
  3. Email Verification Script using PHP and MySQLi

 

Concept

When user open forgot password page, he will be asked to enter his email. When he enter his email the script will look database if that email exist in database or not. If it exist then script will generate a token and store it to database and send an email with the same token to user. When user open that email and click on link inside that email, he will come back to our website and asked for new password. This is just a little concept behind this script. Let’s see how to do this:

Database

CREATE TABLE `recovery_keys` (

  `rid` int(11) NOT NULL AUTO_INCREMENT,

  `userID` int(11) NOT NULL,

  `token` varchar(50) NOT NULL,

  `valid` tinyint(4) NOT NULL DEFAULT '1',

  PRIMARY KEY (`rid`)

);

Form

Forgot Password Recovery Form
Forgot Password Recovery Form

I have used bootstrap to build my layout. It’s up to you what you prefer while designing your page. Here is my HTML code for the above layout:

<div class="container">

<div class="row">

<div class="col-lg-4">

<form class="form-horizontal" role="form" method="post">

<h2>Forgot Password</h2>

<p>

Forgot your password? No problem, we will fix it. Just type your email below and we will send you password recovery instruction to your email. Follow easy steps to get back to your account.

</p>

<div class="row">

<div class="col-lg-12">

<label class="control-label">Your Email</label>

</div>

</div>



<div class="row">

<div class="col-lg-12">

<input class="form-control" name="uemail" type="email" placeholder="Enter your email here..." required>

</div>

</div>



<div class="row">

<div class="col-lg-12">

<button class="btn btn-success btn-block" name="submit" style="margin-top:8px;">Submit</button>

</div>

</div>

</form>

</div>



</div>

</div>

Note: I am very new to bootstrap, so don’t mind my rough code 😛

 Now let’s move to PHP code. The first and foremost thing is a connection to database. So here is config.php

define('DB_SERVER', 'localhost');

define('DB_USERNAME', 'root');

define('DB_PASSWORD', '');

define('DB_DATABASE', 'database');

$db = mysqli_connect(DB_SERVER,DB_USERNAME,DB_PASSWORD,DB_DATABASE);

Now get back to our index.php, that is where our real form is. Now we will see when user hit submit button we have to process form data. We will look to our database if that email actually exist in database or not. If it exist then we will simple generate a random string and store this string to our recover_keys table along with user unique ID (we will fetch from user’s table) and then email a link to our page forget.php (discussed below).

When user hit submit button.

if(isset($_POST['submit']))

{

                // Code goes here…

}

Now we will process our form data.

$uemail = $_POST['uemail'];

$uemail = mysqli_real_escape_string($db, $uemai);



if(checkUser($uemail) == "true")

{

$userID = UserID($uemail);

$token = generateRandomString();



$query = mysqli_query($db, "INSERT INTO recovery_keys (userID, token) VALUES ($userID, '$token') ");

if($query)

{

$send_mail = send_mail($uemail, $token);



if($send_mail === 'success')

{

$msg = 'A mail with recovery instruction has sent to your email.';

$msgclass = 'bg-success';

}else{

$msg = 'There is something wrong.';

$msgclass = 'bg-danger';

}

}else

{

$msg = 'There is something wrong.';

$msgclass = 'bg-danger';

}



}else

{

$msg = "This email doesn't exist in our database.";

$msgclass = 'bg-danger';

}

I have used $msgclass here to change the notification color as per message type. I have used some custom-build functions in above code like checkUser(), userID(), generateRandomString() and mail_send(). These are as follow:

Function 1: checkUser()

This function check our database if the given email is existing in database or not. If it exist, it will return true and if not then false.

function checkUser($email)

{
          global $db;
          $query = mysqli_query($db, "SELECT uid FROM users WHERE email = '$email'");
          if(mysqli_num_rows($query) > 0)
          {
              return 'true';
          }else
          {
              return 'false';
          }
}

Function 2: UserID()

This function will return user unique ID if given email exist in database.

function UserID($email)

{

             global $db;

            $query = mysqli_query($db, "SELECT uid FROM users WHERE email = '$email'");

             $row = mysqli_fetch_assoc($query);

              return $row['uid'];

}

Function 2: generateRandomString()

This function generate a random string that can be used as a password recovery token.

function generateRandomString($length = 20) {

                // This function has taken from stackoverflow.com



                $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

                 $charactersLength = strlen($characters);

                $randomString = '';

                for ($i = 0; $i < $length; $i++)

{

                                $randomString .= $characters[rand(0, $charactersLength - 1)];

                }

    return md5($randomString);

}

Function 4: send_mail()

This function is very important function, it is use to send email to user. It’s a PHPMailer class that use to send secure emails. I already have covered an article on PHPMailer. You can read it from here.

function send_mail($to, $token)

{

                require 'PHPMailer/PHPMailerAutoload.php';



                $mail = new PHPMailer;



                $mail->isSMTP();

                $mail->Host = 'smtp.gmail.com';

                $mail->SMTPAuth = true;

                $mail->Username = 'your_gmail@gmail.com';

                $mail->Password = 'your_gmail_password_';

                $mail->SMTPSecure = 'ssl';

                $mail->Port = 465;



                $mail->From = 'your_gmail@gmail.com;

                $mail->FromName = 'Sender’s Name';

                $mail->addAddress($to);



                $mail->isHTML(true);



                $mail->Subject = 'Demo: Password Recovery Instruction';

                $link = 'http://demos.eggslab.net/forgot-password-recovery-script/forget.php?email='.$to.'&token='.$token;

                $mail->Body    = "<b>Hello</b><br><br>You have requested for your password recovery. <a href='$link' target='_blank'>Click here</a> to reset your password. If you are unable to click the link then copy the below link and paste in your browser to reset your password.<br><i>". $link."</i>";



                $mail->AltBody = 'This is the body in plain text for non-HTML mail clients';



                if(!$mail->send()) {

                                return 'fail';

                } else {

                                return 'success';

                }

}

Email Sample
This is how email look like.

Function 5: verifytoken()

When user submit his email to our form. An email will be send to his email account with a link to password recovery page. When user land on this page we need to validate that token with which user land on recovery page. So for this purpose following function will help us to verify that code.

function verifytoken($userID, $token)

{             

        global $db;

        $query = mysqli_query($db, "SELECT valid FROM recovery_keys WHERE userID = $userID AND token = '$token'");

        $row = mysqli_fetch_assoc($query);     

        if(mysqli_num_rows($query) > 0)
        {

            if($row['valid'] == 1)
            {
              return 1;
            }else
            {
              return 0;
            }
        }else
        {
             return 0;
        }
}

The above function will check whether token code and email exist in our database or not. If it exist then it will ask user to set new password otherwise it will prompt that your “Invalid or Broken Token”.

Reset Password Landing Page
Reset Password Landing Page
Invalid or Broken Landing Page
Invalid or Broken Landing Page

After your password change successfully, its time to change recovery_key table to avoid any bad situation. So here is the code in forget.php file that will update recovery_key table and change valid column to 0 and it will never be use again. That’s all.

LIVE DEMODOWNLOAD

I have done my best to explain this article. If you find any bug or mistake in article or code you can feel free to inform though comment or by email at abdullah@eggslab.net.

31 COMMENTS

  1. I still not figure out the There is something wrong. msg the token are generated but still not able to get an email notification.

  2. $query = mysqli_query($db, “INSERT INTO recovery_keys (userID, token) VALUES ($userID, ‘$token’) “);

    should be:

    $query = mysqli_query($db, “INSERT INTO recovery_keys (userID, token) VALUES (‘$userID’, ‘$token’) “);

  3. Hi Abdullah. I’m also getting the ‘There is something wrong message’ it seems to relate to this line: $send_mail = send_mail($uemail, $token);

    I was wondering if it should be ‘$send_mail = send_mail($$userID, $token);’ as you earlier defined $userID = UserID($uemail);

    I tried this change but it didn’t make any difference – I was still getting the same ‘There is something wrong message’ so I changed back to ‘$send_mail = send_mail($$userID, $token);’

    Also – I was wondering, I am testing this on my local development server using WAMP. Could this be the cause of the issue at all?

    Many thanks,

    Adam

  4. Thanks for the code! I am getting an error after I hit submit. It sends the token over and puts the correct UserID in the database but errors out with “There is something wrong” message. Can you please give some insight on why this may be happening? i have looked over the gmail settings and made sure they are correct.
    Thanks for your help!

  5. You can do that by multiple ways. One of them is to store link generation time in database, and then when user click on that link compare that link with current time.

  6. What’s up i am kavin, its my first time to commenting anyplace, when i read this article
    i thought i could also create comment due to this good
    post.

Leave a Reply