Laravel's default for resetting user passwords includes all three fields, i.e email, password and password_confirmation.
Bit of a Background
Here we'll walk around brief steps on how Laravel Password Reset actually works.
When you setup a new Laravel project and run php artisan migrate
for the first time, it ships with default users
and password_resets
tables. Default routes for password reset include a couple of steps.
Password Recover app.local/recover
/**
* @param Request $request
*
* @return JsonResponse
*/
public function recover( Request $request ) {
$request->validate( [
'email' => 'required|string|email',
] );
$user = User::where( 'email', $request->email )->first();
if ( ! $user ) {
return response()->json( [
'error' => true,
'message' => 'We cannot find a user with that Email Address'
], 404 );
}
$passwordReset = PasswordReset::updateOrCreate(
[ 'email' => $user->email ],
[
'email' => $user->email,
'token' => str_random( 60 )
]
);
if ( $user && $passwordReset ) {
$user->notify(
new PasswordResetRequest( $passwordReset->token )
);
}
return response()->json( [
'error' => false,
'message' => 'We've emailed you your Password reset link.'
] );
}
Password Reset app.local/reset
/**
* @param Request $request
*
* @return JsonResponse
*/
public function reset( Request $request ) {
$request->validate( [
'email' => 'required|string|email',
'password' => 'required|string|confirmed',
'token' => 'required|string'
] );
$passwordReset = PasswordReset::where( [
[ 'token', $request->token ],
[ 'email', $request->email ]
] )->first();
if ( ! $passwordReset ) {
return response()->json( [
'error' => true,
'message' => 'This Password Reset token is invalid.'
], 404 );
}
$user=User::where( 'email', $passwordReset->email )->first();
if ( ! $user ) {
return response()->json( [
'error' => true,
'message' => 'We cannot find a user with that Email Address'
], 404 );
}
$user->password = bcrypt( $request->password );
$user->save();
$passwordReset->delete();
$user->notify( new PasswordResetSuccess( $passwordReset ) );
return response()->json( [
'error' => false,
'message'=>'Your Password changed successfully.'
] );
}
On Password Recover, you'll receive a email with a token and a temporary record has been created against the email with a temporary token in password_resets
table which is to be used for a single time only.
Now if we don't want to input email on reset page, we can make slight changes to our reset API to take effect.
The Solution
Also Read: Advantages of Mailchimp
/**
* @param Request $request
*
* @return JsonResponse
*/
public function reset( Request $request ) {
$request->validate( [
'password' => 'required|string|confirmed',
'token' => 'required|string'
] );
$passwordReset = PasswordReset::where( [
[ 'token', $request->token ]
] )->first();
if ( ! $passwordReset ) {
return response()->json( [
'error' => true,
'message' => 'This Password Reset token is invalid.'
], 404 );
}
$userEmail = DB::table( 'password_resets' )->where( 'token', $passwordReset->token )->pluck( 'email' );
$user = User::where( 'email', $userEmail )->first();
if ( ! $user ) {
return response()->json( [
'error' => true,
'message' => 'We cannot find a user with that Email Address'
], 404 );
}
$user->password = bcrypt( $request->password );
$user->save();
$passwordReset->delete();
$user->notify( new PasswordResetSuccess( $passwordReset ) );
return response()->json( [
'error' => false,
'message'=>'Your Password changed successfully.'
] );
}
If you notice, we're now fetching email based on the request token and rest everything then works exactly the same.
It may not be the perfect solution to this, but seems perfectly fine trick to get the job done in no time.
Try it out & let us know in the comments below.
Learn more about Modifying Password Reset Email Text