I am tring to add an expiration time of 30 minutes to my reset password link but I'm stucked for loooong time. I'm usding PHPMailer for sending email. In my DB I have added a token and expire_token_time for the link but I don't know how to set a limit time of 30 minutes to this link? here is my code:
$reset_token = bin2hex(random_bytes(16));
// created and expiration token date
date_default_timezone_set('Europe/Paris');
$token_date = date('Y-m-d H:i:s');
$date = new DateTime($token_date);
$date->add(new DateInterval('PT30M')); // add 30 minutes to token
$expire_token = $date->format('Y-m-d H:i:s');
//Content
$mail->isHTML(true); //Set email format to HTML
$mail->Subject = 'Reset Password ';
// here is my link to users mail box
// how i keep this link active for 30 minutes ?
$mail->Body = "To reset your password click the link bellow <br />
<a href='http://localhost/varprospects/changePassword.php?token=" .
$reset_token . "' > Change Your Password </a> <br /> The link will be expired
in 30 minuntes!
";
// find the requested user's password
$selectStmt = $conn->prepare("SELECT email,password from var WHERE email=:email");
$selectStmt->bindParam(':email', $email);
$selectStmt->execute();
if ($selectStmt->rowCount() == 1) {
$row = $selectStmt->fetch(PDO::FETCH_ASSOC);
if ($row) {
// if the user exist i add the random token and it's epiration date to the DB
$updateStmt = $conn->prepare("UPDATE var SET token = :token, token_expire = :tokenExpire WHERE email = :email;");
$updateStmt->bindParam(':token', $reset_token);
$updateStmt->bindParam(':tokenExpire', $expire_token);
$updateStmt->bindParam(':email', $email);
$updateStmt->execute();
$mail->send();
echo "<p class='text-center font-weight-bold mt-5'> Please check your email </p>
<p class='text-center'> An email has been set to the following adresse: <br />" . $row['email'] . "</p> ";
} else {
echo "Email doesn't exist !";
}
I am not sure should i insert the token expiration datetime to DB or no the creation datetime. because the time token generate and expire, there is 30 minutes difference. thanks in advance.
CodePudding user response:
I am not sure should i insert the token expiration datetime to DB or no the creation datetime
...it doesn't really matter. The point is that when you receive the token, you should compare that stored time to the current time, and act accordingly.
However I'd say it might be a little bit better to set the expiration time in the database. That way you're not relying on a second piece of data (the timeout period) in order to check whether the token has expired, so it's simpler. But that's really the only difference.
If you need to know how to compare two datetimes in PHP and see which is greater, there are lots of existing resources which cover that process in detail.
CodePudding user response:
Use Event Scheduler. It will disable expired tokens automatically.
CREATE EVENT disable_old_pw_reset_token
ON SCHEDULE EVERY 1 MINUTE
DO
UPDATE var SET token = NULL WHERE token_expire < CURRENT_TIMESTAMP;
I assume that token_expire
stores expiration datetime value.
The presence of the index by token_expire
(by single column or as a prefix) is reasonable.
Do not forget to enable Event Scheduler.