Creating a forgot password function

Let me add my 2 cents to the discussion. I’ve done remind password links a couple of times and the thing is you do not need any additional fields in the database - you do not need to store the code (like “1e95adc9836860c28642”) nor the time in the database and still be able to verify the links and make them expire after a certain amount of time.

The thing is you put both the email address and the time of link generation directly to the remind password link, and you don’t need to encode or encrypt them (neither the email address nor the time is sensitive information in this case). But you add an additional hash that you will use to check the validity of the link - if it has not been tampered with. For example:


where time is simply the result of time() function when the link was generated. The hash is computed from the email, time and salt - the salt is any string to make the process of hacking the verification more difficult. For example, when generating the link you create the hash like this:

$email = "";
$time = time();  // e.g. 1478170183;
$salt = "My cat eats cream";  // or better yet use some random string!

$hash = sha1($email . $time . $salt);

and you put $email, $time and $hash in the link that is sent to the user.

When you verify the link you take $email and $time and compute the hash in the same way as above using the same salt. And you compare the computed hash with the hash from the link - it they match then the link is valid.

In this way you have the email so you can find the user in the database. You also have the generation time so you can check if the link is fresh enough. And the hash verification makes sure the user didn’t change anything in the link - if he changes the email or the timestamp the hash will be different and the verification will fail. The user will not be able to compute the hash because he doesn’t know the algorithm nor the salt. Instead of the email you can use a user ID or any other value that uniquely identifies a user and is not secret information.

And this way you have verification links without needing any additional fields in the database :wink: