php Laravel -如何使用Hash::needsRehash()?

zc0qhyus  于 2023-04-10  发布在  PHP
关注(0)|答案(4)|浏览(132)

我想知道如何使用Hash::needsRehash(),因为我很难看到使用文档的确切用途。

if (Hash::needsRehash($hashed)) {
    $hashed = Hash::make('plain-text');
}

究竟是什么原因导致Hash::needsRehash()返回true或false,如果哈希密码是在另一个哈希中(如MD5,SHA1等),它会返回true吗?
如果你的数据库中充满了另一种算法的哈希值,而Hash::needsRehash()返回true,你如何重新哈希用户的密码,使其是最新的?你不能依赖于“登录”密码,因为它需要首先进行比较以验证,对吗?
我想也许是我想多了,但我现在很困惑。幸运的是,我的用户密码是使用password_hash(),所以不应该是一个问题。

b4wnujal

b4wnujal1#

Hash::needsReHash()只是调用php内置的password_needs_rehash函数。文档中有一个有用的注解:

// Check if a newer hashing algorithm is available
// or the cost has changed
if (password_needs_rehash($hash, PASSWORD_DEFAULT, $options)) {

所以Hash::needsReHash()当且仅当hashing algorithm改变时返回false(因为你没有传递任何选项,比如cost)。
至于如何以及何时使用它,您只能在拥有用户密码时重新散列用户密码-例如,当他们登录时。因此,在登录过程中,您检查他们存储的密码算法是否与您当前的算法不同,如果是这样,您将用新的密码替换他们存储的密码散列。

ctehm74n

ctehm74n2#

Laravel 5.6好像是这么做的

把它放到你的LoginController中:

protected function authenticated(Request $request, $user) {
    if (Hash::needsRehash($user->password)) {
        $user->password = Hash::make($request->password);
        $user->save();
    }
}

https://laravel.com/docs/5.6/hashing#basic-usage

z2acfund

z2acfund3#

当PHP被更新,并且添加了新的/更好的默认算法或更改了任何其他参数时,该方法返回true。这使您可以自动利用它,而无需更新代码。
当用户登录时使用此方法,因为这是您唯一可以访问纯文本密码的时间。在根据旧散列确认它正确后,您将获取纯文本密码,重新散列它,并将其放回数据库以备将来使用。
举一个假设的例子,假设现在算法是md5() 10 k次。在PHP7中,它被更新为sha512() 15 k次。如果哈希是$count|$algo|$hash,则该方法可以判断哈希何时过期。由于旧算法没有被删除,因此您仍然可以在重新哈希之前使用旧参数验证密码。
注意:显然使用md5()/sha512()是一个坏主意,我只是用它们作为例子。

5n0oy7gb

5n0oy7gb4#

我不知道这里的单词'use'到底是什么意思,但是我从我的经验中发现了这个代码的一个用途是防止密码在Laravel中被多次重新散列。这个函数也告诉Laravel不要散列已经散列的密码。让我给予你一个例子。以前,我有一个在我的Laravel模型中保存密码的代码。

public function setPasswordAttribute($password)
    {       
            $this->attributes['password'] = Hash::make($password);
    }

这段代码的作用是:它在将密码存储到数据库中之前对密码进行了哈希处理,这样我就不必在控制器中的多个函数中调用make:hash函数。

public function logoutOtherDevices();

这个函数所做的是,它把我的密码属性和rehash它,但由于我的模型也散列密码存储在数据库中之前,有一个双散列,我的密码从来没有工作后,使用注销其他设备功能和用户必须使用忘记密码功能每一次。现在,当我使用哈希::needsRehash(),它解决了问题的双重散列存储前和密码问题得到解决。下面是我如何实现它在我的模型。

public function setPasswordAttribute($password)
    {
        // Check if the given password is already hashed
        if (Hash::needsRehash($password)) {
                // If it is not hashed, hash it before setting the attribute
                $this->attributes['password'] = Hash::make($password);
        } else {
            // If it is already hashed, don't hash it again
            $this->attributes['password'] = $password;
        }
    }

所以总结一下:你也可以用它来防止你的密码被哈希两次,并可能防止密码错误。这完全是基于我的经验。

Laravel文档也试图提出类似的建议
https://laravel.com/docs/10.x/hashing#determining-if-a-password-needs-to-be-rehashed

相关问题