-
Notifications
You must be signed in to change notification settings - Fork 11.4k
[10.x] Support rehashing user passwords with BC support #48673
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f4522a8
d24b3fe
74a3642
a94f5e5
1cc1e56
adcb353
57a3de9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -152,7 +152,38 @@ public function validateCredentials(UserContract $user, array $credentials) | |
return false; | ||
} | ||
|
||
return $this->hasher->check($plain, $user->getAuthPassword()); | ||
if (! $this->hasher->check($plain, $hash = $user->getAuthPassword())) { | ||
return false; | ||
} | ||
|
||
$this->rehashIfRequired($user, $hash, $plain); | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* Rehash the user's password if required. | ||
* | ||
* @param \Illuminate\Contracts\Auth\Authenticatable $user | ||
* @param string $hash | ||
* @param string $plain | ||
* @return void | ||
*/ | ||
protected function rehashIfRequired(UserContract $user, string $hash, string $plain) | ||
{ | ||
$attribute = method_exists($user, 'getAuthPasswordName') ? $user->getAuthPasswordName() : 'password'; | ||
|
||
if (! isset($user->{$attribute}) || ! hash_equals($hash, $user->{$attribute})) { | ||
return; | ||
} | ||
|
||
if (! $this->hasher->needsRehash($hash)) { | ||
return; | ||
} | ||
|
||
$user->forceFill([ | ||
$attribute => $this->hasher->make($plain), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would this not be a BC for those of us who use an protected function password(): Attribute
{
return new Attribute(
set: fn (string $value): string => Hash::make($value),
);
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, it probably would. The built-in hash cast checks if it's hashed before hashing:
But a custom cast like your example wouldn't do this. 🤔 |
||
])->save(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This potentially may trigger |
||
} | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now the hash gets checked twice (once in
validateCredentials
and here).I guess this is done to be able to make this a public method so it won't rehash passwords that don't match the user's password. But the downside is double hash checking for every login attempt.
Would it make more sense to split this in two methods, one private without the hash check and one public that uses the private method after validating the hash?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hash_equals()
is a basic string comparison function, I could have used===
, but it's best practice to use that for hashes.You're thinking of
password_verify()
.