7

Beginning with Laravel 5.3, this middleware was added...

\Illuminate\Session\Middleware\AuthenticateSession

While it's definitely a benefit for security purposes, it's also responsible for logging the user out (presenting the user with the login page) if they change their password.

How do we prevent a user from being logged out (being forced to log back in) when they change their password, in Laravel 5.5?

Karl Hill
  • 12,937
  • 5
  • 58
  • 95
mcpacific
  • 165
  • 2
  • 12

7 Answers7

9

Instead of changing the middleware, just "re-login" the user after changing the password:

<?php
//$user->passwordChangeMagicHere()

Auth::login($user);
//And the user is logged in again!
manniL
  • 7,157
  • 7
  • 46
  • 72
  • This works but only on HTTP request. If I want to reset via CURL call, then what should I do. Making user login again won't work here. What I noticed, user always getting signed out while updating password. It doesn't matter whether it an API call or HTTP method. You have any other method to prevent this? Especially for CURL API update – Jickson Johnson Koottala Aug 23 '18 at 17:10
8

What worked for me was, to logout, clear session, then login again

Auth::guard('web')->logout();
Session::flush();
Auth::guard('web')->login($this);
1

just a side note, sometimes you might have to update the password_hash of your session. best way inorder to complete the update password process.

auth()->login($user, true);

 $request->session()->put([
            'password_hash' =>  $newUser->getAuthPassword(),
        ]);

it's important you do this after logging in the user again or else, further calls to

auth()->user();

would return null.

1

For the Laravel > 8.x

When the password_hash of the session is different from the current auth()->user() the laravel will automatically logout the user. This is done on this middleware:

vendor/laravel/framework/src/Illuminate/Session/Middleware/AuthenticateSession.php

If you update the password_hash on the session with the new hash password the user will be not logout.

session()->put([
   'password_hash_' . auth()->getDefaultDriver() => $user->getAuthPassword()
]);

Example:

session()->put([
   'password_hash_web' => "$2y$10$...hashpasswordstoredondatabase"
]);
Eduardo Ramos
  • 496
  • 4
  • 12
1

For the Laravel > 8.x

Better way:

// $user - user model after password change
auth()->setUser($user);
0

What worked for me in a Laravel 8 project, as derived from the answers of manniL (use of Auth::login) and Lukmon Awoyemi (use the remember me functionality):

public function updatePassword(UpdatePasswordRequest $request) {
    $user = $request->user();
    $user->fill([
        'password' => Hash::make($request->password),
    ])->save();

    // make sure to re-login the user
    Auth::login($user, !!$user->getRememberToken());

    $request->session()->flash('status', 'Password updated!');
    return redirect()->route('some.route');
}

The UpdatePasswordRequest is just a form request which validates the given original and new passwords, checking that the original password provided is valid and the new password is confirmed.

The addition here is to first check for a remember token. This check will return a token or null if no remember token was set. This information will be converted to boolean and provided to the login function.

Logging in the user like this will make sure that all necessary password and login hashes are updated in the session to match the new password hash. Therefore, the AuthenticateSession middleware will still recognize the user as being logged in. Also, the user is remembered if and only if s/he was remembered before the password change.

Marten Koetsier
  • 3,389
  • 2
  • 25
  • 36
0

You can solve it by using update method instead of save:

$user = auth()->user();

$user->update([
    'password' => Hash::make($data['new_password']),
]);
Mouad ZIANI
  • 132
  • 1
  • 8