From ec5fe817332b4ebe0ea74e130053c218cc0f7baa Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 8 Jun 2022 11:58:47 +0900 Subject: [PATCH 1/2] feat: prevent logged in user tries to login again If a logged-in user logs in with a different user account, the session data of the previous user is carried over. --- src/Authentication/Authenticators/Session.php | 14 +++++++++++++ .../SessionAuthenticatorTest.php | 21 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/Authentication/Authenticators/Session.php b/src/Authentication/Authenticators/Session.php index ffc54517a..b6f4b6b6d 100644 --- a/src/Authentication/Authenticators/Session.php +++ b/src/Authentication/Authenticators/Session.php @@ -550,6 +550,20 @@ private function checkRememberMeToken(string $remember) */ public function startLogin(User $user): void { + /** @var int|string|null $userId */ + $userId = $this->getSessionKey('id'); + + // Check if already logged in. + if ($userId !== null) { + throw new LogicException( + 'The user has User Info in Session, so already logged in or in pending login state.' + . ' If a logged in user logs in again with other account, the session data of the previous' + . ' user will be used as the new user.' + . ' Fix your code to prevent users from logging in without logging out or delete the session data.' + . ' user_id: ' . $userId + ); + } + $this->user = $user; // Regenerate the session ID to help protect against session fixation diff --git a/tests/Authentication/Authenticators/SessionAuthenticatorTest.php b/tests/Authentication/Authenticators/SessionAuthenticatorTest.php index 171a7e5cf..2a59f9e6e 100644 --- a/tests/Authentication/Authenticators/SessionAuthenticatorTest.php +++ b/tests/Authentication/Authenticators/SessionAuthenticatorTest.php @@ -7,6 +7,7 @@ use CodeIgniter\Shield\Authentication\Authenticators\Session; use CodeIgniter\Shield\Config\Auth; use CodeIgniter\Shield\Entities\User; +use CodeIgniter\Shield\Exceptions\LogicException; use CodeIgniter\Shield\Models\RememberModel; use CodeIgniter\Shield\Models\UserModel; use CodeIgniter\Shield\Result; @@ -340,6 +341,26 @@ public function testAttemptSuccess(): void ]); } + public function testAttemptUserHavingSessionDataAttemptsAgain(): void + { + $_SESSION['user']['id'] = '999'; + + $this->expectException(LogicException::class); + $this->expectExceptionMessage( + 'The user has User Info in Session, so already logged in or in pending login state.' + ); + + $this->user->createEmailIdentity([ + 'email' => 'foo@example.com', + 'password' => 'secret123', + ]); + + $result = $this->auth->attempt([ + 'email' => $this->user->email, + 'password' => 'secret123', + ]); + } + public function testAttemptCaseInsensitive(): void { $this->user->createEmailIdentity([ From 9c7b36a721f53d326d94a9dd63263807c719468f Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 11 Jun 2022 12:53:22 +0900 Subject: [PATCH 2/2] refactor: run rector --- .../Authentication/Authenticators/SessionAuthenticatorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Authentication/Authenticators/SessionAuthenticatorTest.php b/tests/Authentication/Authenticators/SessionAuthenticatorTest.php index 2a59f9e6e..0c85ba70c 100644 --- a/tests/Authentication/Authenticators/SessionAuthenticatorTest.php +++ b/tests/Authentication/Authenticators/SessionAuthenticatorTest.php @@ -355,7 +355,7 @@ public function testAttemptUserHavingSessionDataAttemptsAgain(): void 'password' => 'secret123', ]); - $result = $this->auth->attempt([ + $this->auth->attempt([ 'email' => $this->user->email, 'password' => 'secret123', ]);