Prevent logout Jetstream (Inertia)

I installed Jetstream and used the Inertia scaffolding. It's working fine, I'm able to add custom fields in the Profile information.

However, when I change the currently logged-in user's password it is logging out. I haven't modified any middleware that came from Jetstream or Fortify.

I checked the Illuminate\Session\Middleware\AuthenticaSession middleware of Jetstream and noticed the below code:

if ($request->session()->get('password_hash_'.$this->auth->getDefaultDriver()) !== $request->user()->getAuthPassword()) {
    $this->logout($request);
}

Has anyone overridden this before to prevent logging out after changing the password of the currently logged-in user?

Things I tried:

Modify the UpdateUserPassword action:

$user->forceFill([
    'password' => Hash::make($input['password']),
])->save();

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

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

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

// and ...

$user->forceFill([
    'password' => Hash::make($input['password']),
])->save();

request()->session()->forget('password_hash_web');

Auth::guard('web')->login($user);
whoami (Daryl)
whoami (Daryl)
0
6
554
Haz
Haz
Moderator

Not at my desk at the moment but, could you share your view, route, and controller logic? Are you able to reproduce this issue in a fresh Laravel project with Jetstream without any changes, or custom fields?

whoami (Daryl)
whoami (Daryl)

There are no changes in the controller logic.

But I updated the UpdateUserProfileInformation action to add one field, which is working fine.

About the routes, I followed Alex's tutorial to copy the fortify and jetstream routes to the project's routes folder and require them inside the web.php

// routes/web.php

require_once __DIR__.'/fortify.php';
require_once __DIR__.'/jetstream.php';

In fortify.php routes, I added one route:

Route::group(['middleware' => config('fortify.middleware', ['web'])], function () {
    $enableViews = config('fortify.views', true);

    // Authentication...
    if ($enableViews) {
        // added this, to set the login as the homepage
        Route::get('/', [AuthenticatedSessionController::class, 'create'])
            ->middleware(['guest:'.config('fortify.guard')]);

        Route::get(RoutePath::for('login', '/login'), [AuthenticatedSessionController::class, 'create'])
            ->middleware(['guest:'.config('fortify.guard')])
            ->name('login');
    }

In jetstream.php routes, I change the profile endpoint:

Route::group(['middleware' => config('jetstream.middleware', ['web'])], function () {
    // ... 

    Route::group(['middleware' => array_values(array_filter([$authMiddleware, $authSessionMiddleware]))], function () {
        // User & Profile...
        // from /user/profile, I changed it to just /profile
        Route::get('/profile', [UserProfileController::class, 'show'])
            ->name('profile.show');

Are you able to reproduce this issue in a fresh Laravel project with Jetstream without any changes, or custom fields?

I haven't tried it yet, I'll try to install a fresh Laravel app with Jetstream & Fortify and will update this.

EDIT:

I've set up a fresh Laravel app with Jetstream (Inertia) stack and am able to reproduce it.

  1. Install Laravel, and choose Jetstream - Inertia stack.
  2. Run the newly installed app
  3. Register an account
  4. Go to Profile > update password

After submitting the update password form, it will redirect to the login page.

Haz
Haz
Moderator

Hello,

Taking a look into this now. I'll update here shortly. At first glance, this issue happens even without overriding the Jetstream routes, I'm wondering if it's intended as a feature.

Haz
Haz
Moderator
Solution

This really had me beat, but I found a solution.

It seems to only happen with the Inertia stack. I can't reproduce this with the Livewire stack. This doesn't appear to be a feature, at least not an intended one. It's probably wanted behaviour in the sense that it occurs when there is an issue. As shown in your post above.

if ($request->session()->get('password_hash_'.$this->auth->getDefaultDriver()) !== $request->user()->getAuthPassword()) {

It is failing to validate the hash.

The default jetstream.php config has the following configuration:

'auth_middleware' => 'auth',

But in the jetstream.php config created during the installation process has:

use Laravel\Jetstream\Http\Middleware\AuthenticateSession;

'auth_session' => AuthenticateSession::class,

From my tests, it looks like this is causing problems. It doesn't seem to matter which valid middleware you use, it logs out the user.

What's strange is that Livewire has this exact same configuration. I haven't yet dived too deep, but it could potentially be stack-related. For now, you can work around it by doing one of two things.

  1. Remove the line so it defaults to 'auth'

  2. Manually set it to 'auth'

I'll try to find some time to dig deeper into the issue. If I find anything, I'll provide an update here. It might be worth opening a discussion on the appropiate Laravel GitHub to get more insight from the team.

Are you using php artisan serve by the way?

Remember to clear your config cache.

whoami (Daryl)
whoami (Daryl)

Hey Haz, thanks for looking into this.

Sorry, I didn't get this one "Remove the line so it defaults to 'auth'".

And with "Manually set it to 'auth'" do you mean: 'auth_session' => 'auth'?

Are you using php artisan serve by the way?

Yeah, I'm using php artisan serve.

Haz
Haz
Moderator

Hello,

Sorry, I didn't get this one

If you remove the line from the config, it will use the default, auth, which is the same as setting it manually.