I’m writing a simple password-recovery function for the website I’m developing and I was wondering about the expire time.
Getting to the point, I want to add an expire time of around 48h for the reset password link I’m gonna send. Do I have to create a new column to store the current time and check it out some time later to see if its still valid, or is there a simpler way?
That’s my code so far:
public function forgotPass($email) {
$bd = new Bd();
$conn = $bd->connect();
$stt = $conn->prepare("SELECT * FROM Users where email=?");
$stt-> bind_param("s",$email);
$stt-> execute();
$result = $stt->get_result();
if (mysqli_num_rows($result) == 1) {
$stt = $conn->prepare("INSERT INTO Users(recovery) VALUES(?)");
$recovery = $this->randHash(8);
if (!$recovery)
return false;
$stt-> bind_param("s",$recovery);
$stt-> execute();
}
}
and here’s my randHash code:
private static function randHash($lenght) {
if (!filter_var($lenght, FILTER_VALIDATE_INT)) {
return false;
}
$allowed = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
$max = strlen($allowed) - 1;
for ($i=1;$i<=$lenght;$i++) {
$hash .= $allowed[mt_rand(0, $max)];
}
return $hash;
}
Just save the expiration time with the reset token in the database, and when the time has expired just don’t accept the reset token anymore. This is by far the easiest and safest method.
Another way would be creating a reset hash, appending the time, and encrypting that with a secret key. Decrypt and check the timestamp when you check the hash. If the key leaked, however, this method becomes as weak as just putting it in plain text in the URL.