I’m having some problems trying to extend or change a part of the Laravel Framework. Simply I cannot figure out where I can add or edit so that my changes will not be made in the vendor folder.
Essentially my issue was implementing Password Reset functionality to my React/Laravel application. I use inertia to post the reset password form, and it gives the error as follows:
ErrorException password_verify() expects parameter 1 to be string, array given
I use Bcrypt to hash the passwords, so as a workaround I added a couple lines of code to the check function of vendor/laravel/framework/src/Illuminate/Hashing/BcryptHasher.php:
if (is_array($value)) { $value = array_values($value)[0]; }
So now the whole function looks like this:
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); }
I can also make the same change in the parent, AbstractHasher, within its check function and this also resolves the error.
This works, but I need to find a solution to implement this fix without making the changes inside the vendor folder. I deploy the app to google app engine so the changes within the vendor folder will not work in my situation. I just need to know how I can either extend or overwrite the BcryptHasher.php or AbstractHasher.php file properly.
Note: This is my first post here, so hopefully I did not format the message too poorly. If any additional information is required I will provide it. Thanks in advance.
Advertisement
Answer
To resolve the issue, I adapted @apokryfos answer How to change login hash bcrypt to hash256 to work with BcryptHasher instead of trying to add a new hasher such as Sha256.
To do this I made the following changes:
In config/hashing.php Set the driver as custombcrypt for my implementation.
‘driver’ => ‘custombcrypt’,
In app folder
I created a folder named Libraries to hold my custom hasher classes. This folder can be named anything.
In created Libraries folder at app/Libraries
I created a file CustomBcryptHasher.php
<?php namespace AppLibraries; use IlluminateHashingBcryptHasher; 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); } }
The most important part of this file is this small portion near the bottom
if (is_array($value)) { $value = array_values($value)[0]; }
This checks if the value is an array, and if so will extract the first value and use this for the Bcrypt check.
In created Libraries folder at app/Libraries I add created a file named Hash.php which is a copy of /vendor/laravel/framework/src/Illuminate/Support/Facades/Hash.php
<?php namespace IlluminateSupportFacades; /** * @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 IlluminateHashingHashManager */ class Hash extends Facade { /** * Get the registered name of the component. * * @return string */ protected static function getFacadeAccessor() { return 'hash'; } }
In app/Providers I edited the AuthServiceProvider.php to return my CustomBcryptHasher.php when the custombcrypt driver is called.
To do so, I added this code to the boot() function:
Hash::extend('custombcrypt', function () { return new CustomBcryptHasher(); });