Skip to content
John Morris

John Morris

I help freelancers get clients

  • Home
  • About
  • Courses
  • Blog
  • Hire
  • Contact
Menu
  • Home
  • About
  • Courses
  • Blog
  • Hire
  • Contact
Search
Close

How to Create an Email-Based Password Reset Feature For Your Login Script

  • By John Morris
  • December 15, 2017
  • PHP Code Snippets
  • password reset, php login script

Last week, I talked about how to create a session-based login script in PHP. A common feature on these sorts of scripts is a password reset.

Now…

There’s lots of ways to do a password reset. You’ve likely seen many of them. But, I strongly recommend you use an email-based system.

Other systems are 100% dependent on your own system for their security and will make you the primary target of any attacks.

But, with an email-based system… if you secure it properly… a hacker would need to hack the user’s email client. Thus, adding an extra layer of security to your password reset.

With that said, let’s cover how to do it.

First, you need a database table to handle auth tokens for your password reset. Something like this:

<?php
$db->query( "CREATE TABLE IF NOT EXISTS password_reset (
        ID INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
        email VARCHAR(255),
        selector CHAR(16),
        token CHAR(64),
        expires BIGINT(20)
    )");

Having “selector” AND “token” is important to prevent timing attacks. See here for more info on that.

Then, you need a reset form to process the reset request. Like this:

<form action="" method="post">
    <input type="text" class="text" name="email" placeholder="Enter your email address" required>
    <input type="submit" class="submit" value="Submit">
</form>

Next, create our auth token and save it into the database like so:

<?php
// Create tokens
$selector = bin2hex(random_bytes(8));
$token = random_bytes(32);
$url = sprintf('%sreset.php?%s', ABS_URL, http_build_query([
    'selector' => $selector,
    'validator' => bin2hex($token)
]));
// Token expiration
$expires = new DateTime('NOW');
$expires->add(new DateInterval('PT01H')); // 1 hour
// Delete any existing tokens for this user
$this->db->delete('password_reset', 'email', $user->email);
// Insert reset token into database
$insert = $this->db->insert('password_reset', 
    array(
        'email'     =>  $user->email,
        'selector'  =>  $selector, 
        'token'     =>  hash('sha256', $token),
        'expires'   =>  $expires->format('U'),
    )
);

There’s a few things going on here and this code is derived from this post, but the basic idea is to create a random token using random_bytes(), create our URL for email, then hash and store the token in our password_reset table so we can verify incoming password resets against it.

Now, we need to send the email. Like this:

<?php
// Send the email
// Recipient
$to = $user->email;
// Subject
$subject = 'Your password reset link';
// Message
$message = '<p>We recieved a password reset request. The link to reset your password is below. ';
$message .= 'If you did not make this request, you can ignore this email</p>';
$message .= '<p>Here is your password reset link:</br>';
$message .= sprintf('<a href="%s">%s</a></p>', $url, $url);
$message .= '<p>Thanks!</p>';
// Headers
$headers = "From: " . ADMIN_NAME . " <" . ADMIN_EMAIL . ">\r\n";
$headers .= "Reply-To: " . ADMIN_EMAIL . "\r\n";
$headers .= "Content-type: text/html\r\n";
// Send email
$sent = mail($to, $subject, $message, $headers);

At this point, we have database entry with our token (hashed) in it AND an email to the user with the token in the URL for them to click.

Now, we need the page the URL in the email points to and it needs to handle the reset request. That looks like this:

<?php
// Check for tokens
$selector = filter_input(INPUT_GET, 'selector');
$validator = filter_input(INPUT_GET, 'validator');
if ( false !== ctype_xdigit( $selector ) && false !== ctype_xdigit( $validator ) ) :
?>
    <form action="reset_process.php" method="post">
        <input type="hidden" name="selector" value="<?php echo $selector; ?>">
        <input type="hidden" name="validator" value="<?php echo $validator; ?>">
        <input type="password" class="text" name="password" placeholder="Enter your new password" required>
        <input type="submit" class="submit" value="Submit">
    </form>
    <p><a href="index.php">Login here</a></p>
<?php endif; ?>

Then, we need to validate the tokens and reset the password if they’re valid:

<?php
// Get tokens
$results = $this->db->get_results("SELECT * FROM password_reset WHERE selector = :selector AND expires >= :time", ['selector'=>$selector,'time'=>time()]);
if ( empty( $results ) ) {
    return array('status'=>0,'message'=>'There was an error processing your request. Error Code: 002');
}
$auth_token = $results[0];
$calc = hash('sha256', hex2bin($validator));
// Validate tokens
if ( hash_equals( $calc, $auth_token->token ) )  {
    $user = $this->user_exists($auth_token->email, 'email');
    
    if ( false === $user ) {
        return array('status'=>0,'message'=>'There was an error processing your request. Error Code: 003');
    }
    
    // Update password
    $update = $this->db->update('users', 
        array(
            'password'  =>  password_hash($password, PASSWORD_DEFAULT),
        ), $user->ID
    );
    
    // Delete any existing password reset AND remember me tokens for this user
    $this->db->delete('password_reset', 'email', $user->email);
    $this->db->delete('auth_tokens', 'username', $user->username);
    
    if ( $update == true ) {
        // New password. New session.
        session_destroy();
    
        return array('status'=>1,'message'=>'Password updated successfully. <a href="index.php">Login here</a>');
    }
}

Here we grab the token, validate it and then allow the reset if it’s valid. We also make sure to delete the token from the database, so it can’t be used again.

So, that’s it. If you want to keep going with this tutorial, you can on my free tutorial site here: https://johnsfreetuts.com/logintut/

Who else wants to build a thriving freelance business?

I’ve helped 39,413 other freelancers start and grow thriving freelance businesses. Are you next? Subscribe to my Freelance Secrets newsletter and I’ll show you how.
Click here to be next

You might also like

6 Ways to Create a Great Offboarding Experience to Get More Referrals and Repeat Clients In Your Freelance Business

We all know the importance of a first impression. But, I think people often forget just how important a “last impression” is, as well. You

Read More »

7 Ways to Drastically Improve the Service Delivery In Your Freelance Business

It’s funny. This guy came up to me in the grocery store the other day and was like, “Hey man, I can tell you work

Read More »

7 Things to Include In Your Client Onboarding Experience to Make a Great First Impression

Men trust their ears less than their eyes Herodotus Have truer words been spoken? This is where you’re at now. You’ve talked a good game.

Read More »

Freelance Contracts, Payment Terms, Request Forms and All the Details of Getting Paid (And Not Screwed Over)

There’s this great story about John Wooden — who won 10 NCAA basketball championships in 12 years with the UCLA Bruins and was also responsible

Read More »

How to Create an Irresistible Freelance Service Offer – Part 2

“When in doubt, go to the source.” Star Wars: The Clone Wars In our case, that “source” is our offer. Always and forever, if you’re

Read More »

How to Create an Irresistible Freelance Service Offer – Part 1

Value is subjective. That’s not random internet douche, Johnny Freelance, just saying it. It’s the most commonly-accepted (by far) economic theory of value called… surprise,

Read More »
Facebook
Twitter
LinkedIn
Reddit
Pinterest
John Morris

JOHN MORRIS

I’m a 15-year veteran of freelance web development. I’ve worked with bestselling authors and average Joe’s next door. These days, I focus on helping other freelancers build their freelance business and their lifestyles.

PrevPreviousHow to Build a PHP Login Form Using Sessions
NextInheritance In a PHP Class and Object-Oriented ProgrammingNext

Who else wants to build a thriving freelance business?

I’ve helped 39,413 other freelancers start and grow thriving freelance businesses. Are you next? Subscribe to my Freelance Secrets newsletter and I’ll show you how.
Click here to be next

Latest Posts

6 Ways to Create a Great Offboarding Experience to Get More Referrals and Repeat Clients In Your Freelance Business

7 Ways to Drastically Improve the Service Delivery In Your Freelance Business

7 Things to Include In Your Client Onboarding Experience to Make a Great First Impression

Freelance Contracts, Payment Terms, Request Forms and All the Details of Getting Paid (And Not Screwed Over)

How to Create an Irresistible Freelance Service Offer – Part 2

How to Create an Irresistible Freelance Service Offer – Part 1

Success Stories

Ready to add your name here?

Tim Covello

Tim Covello

75 SEO and website clients now. My income went from sub zero to over 6K just last month. Tracking 10K for next month. Seriously, you changed my life.

Michael Phoenix

Michael Phoenix

By the way, just hit 95K for the year. I can’t thank you enough for everything you’ve taught me. You’ve changed my life. Thank you!

Stephanie Korski

Stephanie Korski

I started this 3 days ago, following John’s suggestions, and I gained the Upwork Rising Talent badge in less than 2 days. I have a call with my first potential client tomorrow. Thanks, John!

Jithin Veedu

Jithin Veedu

John is the man! I followed his steps and I am flooded with interviews in a week. I got into two Talent clouds. The very next day, I got an invitation from the talent specialists from Upwork and a lot more. I wanna shout out, he is the best in this. Thanks John for helping me out!

Divyendra Singh Jadoun

Divyendra Singh Jadoun

After viewing John’s course, I made an Upwork account and it got approved the same day. Amazingly, I got my first job the very same day, I couldn’t believe it, I thought maybe I got it by coincidence. Anyways I completed the job and received my first earnings. Then, after two days, I got another job and within a week I got 3 jobs and completed them successfully. All the things he says seem to be minute but have a very great impact on your freelancing career.

Sarah Mui

Sarah Mui

I’ve been in an existential crisis for the last week about what the heck I’m doing as a business owner. Even though I’ve been a business for about a year, I’m constantly trying to think of how to prune and refine services. This was very personable and enjoyable to watch. Usually, business courses like this are dry and hard to get through…. repeating the same things over and over again. This was a breath of fresh air. THANK YOU.

Waqas Abdul Majeed

Waqas Abdul Majeed

I’ve definitely learnt so much in 2.5 hours than I’d learn watching different videos online on Youtube and reading tons of articles on the web. John has a natural way of teaching, where he is passionately diving in the topics and he makes it very easy to grasp — someone who wants you to really start running your business well by learning about the right tools and implement them in your online business. I will definitely share with many of the people I know who have been struggling for so long, I did find my answers and I’m sure will do too.

Scott Plude

Scott Plude

I have been following John Morris for several years now. His instruction ranges from beginner to advanced, to CEO-level guidance. I have referred friends and clients to John, and have encouraged my own daughter to pay attention to what he says. All of his teachings create wealth for me (and happiness for my clients!) I can’t speak highly enough about John, his name is well known in my home.

Sukh Plaha

John is a fantastic and patient tutor, who is not just able to share knowledge and communicate it very effectively – but able to support one in applying it. However, I believe that John has a very rare ability to go further than just imparting knowledge and showing one how to apply it. He is able to innately provoke one’s curiosity when explaining and demonstrating concepts, to the extent that one can explore and unravel their own learning journey. Thanks very much John!

Mohamed Misrab

Misrab Mohamed

John has been the most important person in my freelance career ever since I started. Without him, I would have taken 10 or 20 years more to reach the position I am at now (Level 2 seller on Fiverr and Top Rated on Upwork).

Who else wants to build a thriving freelance business?

I’ve helped 39,413 other freelancers start and grow thriving freelance businesses. Are you next? Subscribe to my Freelance Secrets newsletter and I’ll show you how.
Click here to be next
John Morris

Hi, I’m John. I’m a freelance web developer and online teacher. I help aspiring freelance web developers go full-time as freelancers. I’m on the social media sites below and look forward to connecting with you there.

Facebook-f Youtube Instagram

Navigation

  • About
  • Blog
  • Tutorials
  • Courses
  • Resources
  • Podcast
  • Terms of Service
  • Privacy Policy
  • Earnings Disclaimer
  • Referral Disclaimer

Who else wants to build a thriving freelancing business?

I’ve helped 39,413 other freelancers build their freelance businesses. Are you next? Subscribe to my Freelance Secrets newsletter and I’ll show you how.

Click here to be next

© 2021 IDEA ENGINE LLC. All rights reserved