Expire unix or time() code after x hours
I am trying to create a forgot password feature which will expire the link created after x hours. So I am storing time()
data in database value when 开发者_如何学Pythona user requests a password reset. So how can I expire it?
three options:
- compare the time you saved on the db with the one you get when the user click the link
- Use a cron job and make it run periodically
- Just don't save in the db and make the link to care about everything. You could use a signature + a salt to avoid users to modify this link
like:
$now = time();
$sk = sh1($user_id . $now . "yoursupersalthere")
$link = "http://www.example.com/forgot.php?id={$user_id}&ts={$now}&sk={$sk}"
that will be the link you sent to the user. Then to make the check
$ts = $_GET['ts'];
$user = $_GET['id'];
$sk = $_GET['sk'];
if (!$sk == sh1($user_id . $now . "yoursupersalthere")) {
die("bad signature");
}
elseif (time() - $ts > 3600 /* or put your expiration limit */) {
die('link expired');
}
// do your job
You're probably having a table entry with a reset link, just add a date field to it, and then either include a WHERE expiredate<NOW()
or clean the table from time to time with a simple DELETE from table WHERE expiredata<NOW()
.
One method of doing this is to check to see if the link is expired when the link is clicked -- some pseudo-code:
// when the link is clicked pull the information from the database and get the time
// SQL goes here
// this will give you the difference in seconds
$diff = time() - $timestamp_from_db;
// we'll pretend the time expires in 8 hours
$expires_in = 8 * 60 * 60;
// for this example we'll pretend the expiration is 8 hours
if($diff <= $expires_in)
{
// has not been more then 8 hours
}
else
{
// has been more then 8 hours
}
The best way to do this that keeps the table clean is to implement the following:
- The table needs at least the account ID with a UNIQUE index and foreign key to the accounts table, the hash with a UNIQUE index and a timestamp.
- In the page that creates the link, do not allow "reset my password" based on information that can be obtained by a random person. If you do this, one can fill your table with reset password requests and generate spam and security concerns with your users.
- In the page where the link is verified first delete all expired records by comparing NOW() with the stored timestamp, then simply SELECT using WHERE='$hash' (of course, you sanitize $hash). Given the UNIQUE index on the hash, this can only return one row or no rows.
The UNIQUE index on the account ID ensures that people cannot request multiple resets within the expiration time.
精彩评论