[12.x] Check if internal Hasher::verifyConfiguration()
method exists on driver before forwarding call
#54833
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
While migrating an older application to Laravel 12, I updated its
User
model to start using thehashed
cast for thepassword
attribute, as it is used on the updated skeleton.This application extends the
Illuminate\Hashing\HashManager
to use a custom class which implements theIlluminate\Contracts\Hashing\Hasher
interface. Please read the "motivation" section if you are interested in the reasoning to using a customHasher
implementation.The
Illuminate\Database\Eloquent\Concerns\HasAttributes@castAttributeAsHashedString()
method calls aHash::verifyConfiguration()
method on theHash
façade, which blindly delegates this call to the underlying driver.framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php
Lines 1415 to 1418 in f5e57f0
But the
verifyConfiguration()
method wasn't added to theIlluminate\Contracts\Hashing\Hasher
, and therefore wasn't required to be implemented at first glance.This PR:
HashManager@verifyConfiguration()
method to verify if theverifyConfiguration()
method exists before delegating to the current driver.If this PR is accepted, I can send another PR later to add the
verifyConfiguration()
to theIlluminate\Contracts\Hashing\Hasher
interface, in case it is wanted.Maybe this change should be backported to Laravel 11 - or even Laravel 10, when that check was introduced - as any application using a custom
Hasher
implementation, and moving to use thehashed
cast, would raise this error.As a workaround, I added the
verifyConfiguration()
to the customHasher
implementation.Motivation
The app is from a 30-year-old project (yes, from 1995). I was contracted in 2019 to convert the codebase to Laravel, and earlier this month I was tasked with modernizing it again to the latest Laravel version.
For being such a long-lived application, there were many developers along the way, and many decisions about password hashing were made.
By 2019, each user would have their password hashed using a different hashing mechanism, bound to when them created their account.
What we ended up doing was creating a
Illuminate\Contracts\Hashing\Hasher
implementation for each hashing strategy, and a composite class which aggregates them, including Laravel'sBcryptHasher
, which:Hasher@make()
always uses Laravel'sBcryptHasher
Hasher@check()
iterates over each implementationHasher@needsRehash()
always returnstrue
if we verify it is a legacy hash, otherwise delegates to Laravel'sBcryptHasher
That way, slowly on logging in, the users have their password converted over
bcrypt
.