如何编辑 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();
});
我在尝试扩展或更改 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 的回答
为此,我进行了以下更改:
在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();
});