diff --git a/src/Http/Middleware/AuthenticateSession.php b/src/Http/Middleware/AuthenticateSession.php index 965dae40..fe8d6b99 100644 --- a/src/Http/Middleware/AuthenticateSession.php +++ b/src/Http/Middleware/AuthenticateSession.php @@ -64,12 +64,28 @@ public function handle(Request $request, Closure $next): Response } return tap($next($request), function () use ($request, $guards) { - if (! is_null($request->user())) { - $this->storePasswordHashInSession($request, $guards->keys()->first()); + if (! is_null($guard = $this->getFirstGuardWithUser($guards->keys()))) { + $this->storePasswordHashInSession($request, $guard); } }); } + /** + * Get the first authentication guard that has a user. + * + * @param \Illuminate\Support\Collection $guards + * @return string|null + */ + protected function getFirstGuardWithUser(Collection $guards) + { + return $guards->first(function ($guard) { + $guardInstance = $this->auth->guard($guard); + + return method_exists($guardInstance, 'hasUser') && + $guardInstance->hasUser(); + }); + } + /** * Store the user's current password hash in the session. * @@ -79,12 +95,8 @@ public function handle(Request $request, Closure $next): Response */ protected function storePasswordHashInSession($request, string $guard) { - if (! $request->user()) { - return; - } - $request->session()->put([ - "password_hash_{$guard}" => $request->user()->getAuthPassword(), + "password_hash_{$guard}" => $this->auth->guard($guard)->user()->getAuthPassword(), ]); } } diff --git a/tests/Controller/FrontendRequestsAreStatefulTest.php b/tests/Controller/FrontendRequestsAreStatefulTest.php index 424bff7b..bf82597b 100644 --- a/tests/Controller/FrontendRequestsAreStatefulTest.php +++ b/tests/Controller/FrontendRequestsAreStatefulTest.php @@ -13,7 +13,8 @@ class FrontendRequestsAreStatefulTest extends TestCase { - use RefreshDatabase, WithWorkbench; + use RefreshDatabase; + use WithWorkbench; protected function defineEnvironment($app) { @@ -57,6 +58,13 @@ protected function defineRoutes($router) return $request->user()->email; })->middleware($webMiddleware); + + $router->get('/sanctum/api/logout', function () { + auth()->guard('web')->logout(); + session()->flush(); + + return 'logged out'; + })->middleware($apiMiddleware); } public function test_middleware_keeps_session_logged_in_when_sanctum_request_changes_password() @@ -143,6 +151,28 @@ public function test_middleware_can_deauthorize_valid_user_using_acting_as_after ])->assertStatus(401); } + public function test_middleware_removes_password_hash_after_session_is_cleared_during_request() + { + $user = UserFactory::new()->create(); + + $this->actingAs($user) + ->getJson('/web/user', [ + 'origin' => config('app.url'), + ]) + ->assertOk() + ->assertSee($user->email); + + $this->getJson('/sanctum/web/user', [ + 'origin' => config('app.url'), + ]) + ->assertOk() + ->assertSee($user->email)->assertSessionHas('password_hash_web', $user->getAuthPassword()); + + $this->getJson('/sanctum/api/logout', [ + 'origin' => config('app.url'), + ])->assertOk()->assertSee('logged out')->assertSessionMissing('password_hash_web'); + } + public static function sanctumGuardsDataProvider() { yield [null];