“令牌”在密码重置中扮演什么角色


What part does the "token" play in password reset?

我正在使用 laravel 的身份验证密码重置方法,但不确定我是否完全了解在所有这些中扮演令牌的哪个部分。

  1. 我向用户发送了一封包含 Password::remind('email@email.com') 的电子邮件,这会在我的password_reminders表中生成一个令牌。令牌在 URL 中完全可见。

  2. 用户转到如下所示的 URL:mywebsite.com/remindpass/xxxxxx[token]

  3. 然后他用他的email和一个新的password填写了一份表格,将其发送到一个控制器 - 它使用Password::reset('email','password','xxxxxx')

问题是这如何安全?生成的令牌如何防止某人随心所欲地mywebsite.com/remindpass/xxxxxx[token]和更改电子邮件和密码?

有人可以澄清程序吗?

我相信

有人可以比我更好地回答这个问题。

简短的回答:

令牌使某人更难猜测重置密码所需的凭据,同时使电子邮件中的重置链接可用。

长答案:

在文件vendor/laravel/framework/src/Illuminate/Auth/Guard.php 中,您将看到方法createRememberTokenIfDoesntExist 。此方法实际上引用了它上方的另一个称为 refreshRememberToken 的方法来设置令牌。

它使用 laravel 辅助功能str_random 。如果将此函数追溯到其源代码,您会发现它使用 vendor/laravel/framework/src/Illuminate/Support/Str.php 类的 random 方法。

public static function random($length = 16)
{
    if (function_exists('openssl_random_pseudo_bytes'))
    {
        $bytes = openssl_random_pseudo_bytes($length * 2);
        if ($bytes === false)
        {
            throw new 'RuntimeException('Unable to generate random string.');
        }
        return substr(str_replace(array('/', '+', '='), '', base64_encode($bytes)), 0, $length);
    }
    return static::quickRandom($length);
}

现在我们终于到了构建令牌的位置。此方法使用函数openssl_random_pseudo_bytes生成令牌。您可以在 PHP 手册页中阅读有关该函数的信息openssl_random_pseudo_bytes,但基本上它会生成一个加密强度高的随机字符串。

然后 Laravel 获取此字符串(仍在随机方法中),base 64 对其进行编码,替换一些字符,并根据默认设置 16(在参数定义 $length = 16 中看到)或调用者传递给方法的任何长度获取该字符串的一部分。

因此,您将获得一个加密强度高的字符串,然后作为您的令牌进行操作。

如果您查看文件vendor/laravel/framework/src/Illuminate/Auth/DatabaseUserProvider.php并找到方法retrieveByToken,您将看到 laravel 同时使用用户记录 ID 和令牌来查找需要更改密码的用户。

对于某人来说,猜测该字符串和具有该令牌的用户记录的 ID 将非常困难,并且需要了解应用程序的业务逻辑。

生成的令牌如何防止某人随心所欲地mywebsite.com/remindpass/xxxxxx[token]和更改电子邮件和密码?

因为只有您和您发送电子邮件的人(即帐户持有人)知道令牌是什么。

一个强大的实现将采取措施使难以猜测代币:

  • 长(难以猜测)令牌
  • 限时代币
  • 基于 IP 的访问/remindpass/*速率限制