如何编辑 Laravel 7 AbstractHasher 或 BcryptHasher?

How to edit Laravel 7 AbstractHasher or BcryptHasher?

我在尝试扩展或更改 Laravel 框架的一部分时遇到了一些问题。只是我不知道我可以在哪里添加或编辑,这样我的更改就不会在供应商文件夹中进行。

基本上我的问题是对我的 React/Laravel 应用程序实施密码重置功能。我用惯性post重置密码的形式,报错如下:

ErrorException password_verify() expects parameter 1 to be string, array given

我使用 Bcrypt 对密码进行哈希处理,因此作为一种解决方法,我在 vendor/laravel/framework/src/Illuminate/Hashing/BcryptHasher 的检查函数中添加了几行代码。php:

    if (is_array($value)) {
       $value = array_values($value)[0];
  }

所以现在整个函数看起来像这样:

public function check($value, $hashedValue, array $options = [])
{
    if ($this->verifyAlgorithm && $this->info($hashedValue)['algoName'] !== 'bcrypt') {
        throw new RuntimeException('This password does not use the Bcrypt algorithm.');
    }
    if (is_array($value)) {
        $value = array_values($value)[0];
    }
    return parent::check($value, $hashedValue, $options);
}

我也可以在其检查函数中对父 AbstractHasher 进行相同的更改,这也解决了错误。

这可行,但我需要找到一种解决方案来实施此修复,而无需在 vendor 文件夹中进行更改。我将应用程序部署到 google 应用程序引擎,因此供应商文件夹中的更改在我的情况下不起作用。我只需要知道如何正确扩展或覆盖 BcryptHasher.php 或 AbstractHasher.php 文件。

注意:这是我第一次 post 来这里,所以希望我的邮件格式没有太差。如果需要任何其他信息,我会提供。提前致谢。

如果我没记错的话,您可以使用依赖注入将适当的 Hasher 传递给您的 Guard,因此如果您要扩展 BcryptHasher 并传递它,您的问题就会得到解决。

为了解决这个问题,我修改了@apokryfos 的回答 以使用 BcryptHasher 而不是尝试添加新的哈希器,例如 Sha256。

为此,我进行了以下更改:

在config/hashing.php 为我的实现将驱动程序设置为 custombcrypt。

'driver' => 'custombcrypt',

在应用程序文件夹中

我创建了一个名为 Libraries 的文件夹来保存我的自定义哈希器 类。这个文件夹可以任意命名。

在 app/Libraries

处创建的 Libraries 文件夹中

我创建了一个文件CustomBcryptHasher.php

<?php

namespace App\Libraries;

use Illuminate\Hashing\BcryptHasher;
use RuntimeException;

class CustomBcryptHasher extends BcryptHasher
{
    /**
     * Check the given plain value against a hash.
     *
     * @param  string  $value
     * @param  string  $hashedValue
     * @param  array  $options
     * @return bool
     *
     * @throws \RuntimeException
     */
    public function check($value, $hashedValue, array $options = [])
    {
        if ($this->verifyAlgorithm && $this->info($hashedValue)['algoName'] !== 'bcrypt') {
            throw new RuntimeException('This password does not use the Bcrypt algorithm.');
        }
        if (is_array($value)) {
            $value = array_values($value)[0];
        }
        return parent::check($value, $hashedValue, $options);
    }

}

这个文件最重要的部分是靠近底部的一小部分

    if (is_array($value)) {
       $value = array_values($value)[0];
  }

这将检查值是否为数组,如果是,将提取第一个值并将其用于 Bcrypt 检查。

在 app/Libraries 处创建的 Libraries 文件夹中 我添加创建了一个名为 Hash.php 的文件,它是 /vendor/laravel/framework/src/Illuminate/Support/Facades/Hash.php

的副本
<?php

namespace Illuminate\Support\Facades;

/**
 * @method static array info(string $hashedValue)
 * @method static bool check(string $value, string $hashedValue, array $options = [])
 * @method static bool needsRehash(string $hashedValue, array $options = [])
 * @method static string make(string $value, array $options = [])
 *
 * @see \Illuminate\Hashing\HashManager
 */
class Hash extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'hash';
    }
}

在app/Providers 当调用 custombcrypt 驱动程序时,我将 AuthServiceProvider.php 编辑为 return 我的 CustomBcryptHasher.php。

为此,我将这段代码添加到 boot() 函数中:

Hash::extend('custombcrypt', function () {
    return new CustomBcryptHasher();
});