Skip to content

Commit

Permalink
Fix/unable to logout (#511)
Browse files Browse the repository at this point in the history
* fix user not being able to logout

* fix use auth guard to grab password aswell

* test: write test for hash getting removed from session

* change global auth helper to injected auth factory

* Update AuthenticateSession.php

* instead of checking first guard user the guard that user is authenticated with

* fix style ci complaint

* formatting

* formatting

* formatting

---------

Co-authored-by: Taylor Otwell <taylor@laravel.com>
  • Loading branch information
GigaGiorgadze and taylorotwell authored Apr 10, 2024
1 parent 41097ec commit 9cfc0ce
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 8 deletions.
26 changes: 19 additions & 7 deletions src/Http/Middleware/AuthenticateSession.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -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(),
]);
}
}
32 changes: 31 additions & 1 deletion tests/Controller/FrontendRequestsAreStatefulTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@

class FrontendRequestsAreStatefulTest extends TestCase
{
use RefreshDatabase, WithWorkbench;
use RefreshDatabase;
use WithWorkbench;

protected function defineEnvironment($app)
{
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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];
Expand Down

0 comments on commit 9cfc0ce

Please sign in to comment.