我正在使用 laravel 的身份验证密码重置方法,但不确定我是否完全了解在所有这些中扮演令牌的哪个部分。
-
我向用户发送了一封包含
Password::remind('email@email.com')
的电子邮件,这会在我的password_reminders
表中生成一个令牌。令牌在 URL 中完全可见。 -
用户转到如下所示的 URL:
mywebsite.com/remindpass/xxxxxx[token]
。 - 然后他用他的
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/*
速率限制