如何处理密码使用/过期后的重置请求


How to handle reset-password request after it use/expire

我正在我的网站上建立一个重置密码功能,它工作得很好。但在某些方面我有点不确定。

现在我有一个这样的表:

password_change_request:

ID    |     user_id       |       token       |      created_time

user_id-字段将存储用户的用户名。在token -字段中,将存储生成和加密的令牌。最后在created_time中,将存储请求时间的时间戳。


发出请求:

当用户在Forgot Password表单中输入邮箱时,系统将在users-表中查找该用户是否存在。如果用户确实存在,它将查找该用户的用户名。

它还将通过加密用户的电子邮件以及随机SALT来生成令牌。

然后它将发送一个带有用户名和令牌的链接到输入的电子邮件地址,如http://yoursite.com/login.php?action=reset&token=28130dh29sd129809sda802e&user=yourusername

该令牌在存储在数据库中时将被额外加密。

重置密码:

当用户点击电子邮件中的链接时,它将把用户引导到一个站点,该站点将检查password_change_request-表中是否存在任何请求,并使用给定的用户名和加密令牌。

如果是,它将通过计算数据库中的created_time与当前时间之间的差值来检查请求是否超过2小时。

如果不超过2小时,将出现两个字段,用户可以在其中输入新密码,然后出于安全原因重新输入密码。

当用户输入新密码并点击"Reset"按钮时,将生成该用户的新SALT,并在users-表中更新用SALT加密的新密码。

当新密码已经更新,如果请求超过2小时,请求将从password_change_request-表中删除。


这是一个好方法吗?它的灵感来自WordPress和这个网站上的其他答案。

但是我能找到的一件事是,当它被使用/过期时,请求会发生什么?

应该从数据库中永久删除吗?我似乎找不到另一种方法来做这件事。如果没有这个功能,用户可能只是重复使用链接,一次又一次。

所以除了这是不是一个好方法,主要的问题是如何处理请求后,他们已经使用或过期?

或者我应该把令牌在users表的一列,像WordPress一样,然后只是清除字段,当请求已被使用/过期?

希望有人能帮助我:)

  • TheYaXxE

从文档中查看Laravel Framework是如何做到的。

可以在这里找到源代码。

基本上它要求用户发送一个链接到密码重置与绑定到电子邮件的哈希。验证哈希值,然后输入新密码,并询问新密码确认。

你可以通过查看我在github上链接的源代码来了解更多信息。

// Create a new reminder record and token.
public function create(RemindableInterface $user)
{
    $email = $user->getReminderEmail();
    // We will create a new, random token for the user so that we can e-mail them
    // a safe link to the password reset form. Then we will insert a record in
    // the database so that we can verify the token within the actual reset.
    $token = $this->createNewToken($user);
    $this->getTable()->insert($this->getPayload($email, $token));
    return $token;
}
// Create a new token for the user.
public function createNewToken(RemindableInterface $user)
{
    $email = $user->getReminderEmail();
    $value = str_shuffle(sha1($email.spl_object_hash($this).microtime(true)));
    return hash_hmac('sha1', $value, $this->hashKey);
}
// Determine if the reminder has expired.
protected function reminderExpired($reminder)
{
    $createdPlusHour = strtotime($reminder->created_at) + $this->expires;
    return $createdPlusHour < $this->getCurrentTime();
}

最好将时间包含在散列中。然后,您可以通过带有散列的链接提取用户进入时的时间差。您也可以在使用后清除哈希字段。通过这种方式,您将能够明确地通知用户链接是否已经过期,或者无效,或者根本没有发出挂起请求。

是的,因为您正在使用一个专用的表来完成这个任务,建议简单地完全删除使用的行;为什么要保留它?

其次,您可以解密哈希以提取时间,因为它的顺序与加密时的顺序相同。

   $difference=time()-$extractedTime;       //kindof
   $hoursDifference=ceil($difference/7200); //2*60*60=7200

如果这是有帮助的,请花点时间投票,谢谢。