如何编辑 Laravel 7 AbstractHasher 或 BcryptHasher?

问题描述

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

本质上我的问题是在我的 React/Laravel 应用程序中实现密码重置功能。我用惯性把重置密码表贴出来了,报错如下:

ErrorException password_verify() 期望参数 1 是字符串, 给定数组

我使用 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,$options);
}

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

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

注意:这是我在这里的第一篇文章,所以希望我没有太糟糕地格式化消息。如果需要任何其他信息,我会提供。提前致谢。

解决方法

为了解决这个问题,我调整了@apokryfos 的答案 How to change login hash bcrypt to hash256 以与 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,$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';
    }
}

应用内/提供者 我编辑了 AuthServiceProvider.php 以在调用 custombcrypt 驱动程序时返回我的 CustomBcryptHasher.php。

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

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

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