Looking for a some good options to send users reset password emails

10,564

Solution 1

Here's what I do:

I have reset_password table. When someone asks for a reset, they usually click a link on your site that says "forgot password" where they enter their email they registered with and your system sends a link. Of course you begin with finding out if the user is registered at all. by selecting from users where email = $_POST['email']. If they exist, make a randomly generated token, like

$token = md5($_POST['email'].time());

But as Buh Buh expressed in the comment below, you may want to use something a little less obvious to generate your token. crypt() can accept a salt pattern if you like.

Insert the request (email and token) in the reset_password table, then you send them a link like

http://www.domain.com/resetpassword.php?token=<?php echo $token; ?>

Then in that file you take the $_GET['token'] and cross reference it with the reset_password table. If the token is valid, you present them with a form that asks for their new password. Upon submit, select the user with the email address related to that token and update the user table.

Solution 2

There is a danger of loosing out the url to anyone who sniffs network. To avoid this, you may generate a random short key such as vX4dq and save it in your database. Ask user to remember this. When a user resets via the link, ask him/her to enter this key only known to him.

Advanced :- you may show this key in a captcha so that it doesn't get sniffed.

Share:
10,564
LightningWrist
Author by

LightningWrist

Updated on June 13, 2022

Comments

  • LightningWrist
    LightningWrist almost 2 years

    I want to send emails to users when the forget their passwords that prompt them to reset their passwords. I know this is debatable and was looking for a few good options/suggestions/methods/articles to choose from.

    I'm prompting users to press a 'forgot password' link with a simple script with the PHP portion doing this:

    $Email = $_POST['email'];
    $success = false;
    $formError = false;
    
    if(isset($_POST['sub_forgot_pw'])) {
    
        if(empty($_POST['email'])) {
            $formError = "true";
            $error = "Please enter your e-mail address.";
        }else{
            $to = $Email;
            $subject = "Password Help";
            $message = "To reset your password, please <a href='http://www.blahblahblah.org'>Click here</a><br /><br />Do LIFE,<br /> The Team";
            $from = "CysticLife <[email protected]>";
            $headers  = 'MIME-Version: 1.0' . "\n";
            $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\n";
            $headers .= "From: $from";
            if(mail($to, $subject, $message, $headers));{
                $success = "true";
            }
    
    
        }
    
    }
    
  • Leandro
    Leandro over 11 years
    At least for me $token = md5($_POST['email'].time()); is working better. Without the brackets the variable token it was depending only on the given e-mail address.
  • Buh Buh
    Buh Buh almost 11 years
    (Originally posted by an anonymous user): Do NOT use this advice, it is very insecure. All someone would have to do to reset any password on your site is enter someone's email in the reset blank, and look at their wrist watch, then make the same token themselves. Anyone can know the time to the second, and anyone can take the exact same MD5.
  • Kai Qing
    Kai Qing almost 11 years
    True, but it would have to be exact and they would also have to know this is definitely the method used, which may not be too hard to decipher if even a little effort was put into the hack. But the general concept is not particularly insecure so long as you create token rules that are not easily identified by just looking at the url.
  • TheYaXxE
    TheYaXxE about 10 years
    Buh, Buh: So instead of using time() it is better to create a completely random key like: $key = uniqid(mt_rand(), true); and then create the token like: $token = md5($_POST['email'].$key); or sha1/sha256?
  • Kai Qing
    Kai Qing about 10 years
    @TheYaXxE - yes, pretty much. Point is to create a string and convolute the generation process enough to avoid people trying to guess your methods and hack away.
  • TheYaXxE
    TheYaXxE about 10 years
    @Kai Qing - Great :D But should the request also be deleted after the password has been reset? You know, to make sure that the request cannot be used again and again and again.... :)
  • Kai Qing
    Kai Qing about 10 years
    I usually give the request a date time and treat it as invalid if it is over an hour old. I don't delete the record in case there's a reason to review the history of requests. This all depends on your own needs, so do what makes most sense to you.
  • Yousef Altaf
    Yousef Altaf over 9 years
    @Kai Qing can you please provide the script that you use for forgot your password since I have been searching hours for secure script for forgot ur password
  • Kai Qing
    Kai Qing over 9 years
    It's not really as simple as having a universal script to handle it. The script wouldn't likely match your database structure, site routing, or possibly mail handling anyhow. This answer has enough to guide you on creating the script for your site. Mine is always different depending on the projects because I never know who wrote the code I inherit. But I assure you, this is a pretty easy thing that you can write out in 20 minutes.