From 6f025184251e46b8b46bb985c8fda8110faebe94 Mon Sep 17 00:00:00 2001 From: AlexzPurewoko Date: Sat, 23 Aug 2025 23:47:00 +0700 Subject: [PATCH 1/5] preventing session creation and saving while requesting API --- src/Illuminate/Session/Middleware.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Session/Middleware.php b/src/Illuminate/Session/Middleware.php index 7bad30c0..6bb7e9e4 100644 --- a/src/Illuminate/Session/Middleware.php +++ b/src/Illuminate/Session/Middleware.php @@ -59,10 +59,19 @@ public function handle(Request $request, $type = HttpKernelInterface::MAIN_REQUE { $this->checkRequestForArraySessions($request); - // If a session driver has been configured, we will need to start the session here + // Check if this request is coming either from API or from Oauth access token + $isAPIorOauthRequest = $request->headers->has('Authorization') || + ($request->isMethod('POST') && str_contains($request->getUri(), '/oauth/')) || + str_contains($request->getUri(), '/api/'); + + + // If a session driver has been configured, we will need to start the session here // so that the data is ready for an application. Note that the Laravel sessions // do not make use of PHP "native" sessions in any way since they are crappy. - if ($this->sessionConfigured()) + + // this api has been modified to prevent request from API starting the + // session, and saving the session as we don't need user session here + if (!$isAPIorOauthRequest && $this->sessionConfigured()) { $session = $this->startSession($request); @@ -74,7 +83,10 @@ public function handle(Request $request, $type = HttpKernelInterface::MAIN_REQUE // Again, if the session has been configured we will need to close out the session // so that the attributes may be persisted to some storage medium. We will also // add the session identifier cookie to the application response headers now. - if ($this->sessionConfigured()) + + // this api has been modified to prevent request from API starting the + // session, and saving the session as we don't need user at backend side here + if (!$isAPIorOauthRequest && $this->sessionConfigured()) { $this->storeCurrentUrl($request, $session); $this->closeSession($session); From 920a4ea9295c15fcc8ff7a6b2ffa554522075977 Mon Sep 17 00:00:00 2001 From: AlexzPurewoko Date: Sun, 24 Aug 2025 12:12:16 +0700 Subject: [PATCH 2/5] add containing api/v1 because problem --- src/Illuminate/Session/Middleware.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Session/Middleware.php b/src/Illuminate/Session/Middleware.php index 6bb7e9e4..c7d74473 100644 --- a/src/Illuminate/Session/Middleware.php +++ b/src/Illuminate/Session/Middleware.php @@ -61,7 +61,7 @@ public function handle(Request $request, $type = HttpKernelInterface::MAIN_REQUE // Check if this request is coming either from API or from Oauth access token $isAPIorOauthRequest = $request->headers->has('Authorization') || - ($request->isMethod('POST') && str_contains($request->getUri(), '/oauth/')) || + ($request->isMethod('POST') && str_contains($request->getUri(), 'api/v1/oauth/')) || str_contains($request->getUri(), '/api/'); From 39335c636af8d04fbe07cbaaa6ed4e25e4009518 Mon Sep 17 00:00:00 2001 From: AlexzPurewoko Date: Thu, 28 Aug 2025 14:24:24 +0700 Subject: [PATCH 3/5] only for oauth api request and request with Authorization header --- src/Illuminate/Session/Middleware.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Illuminate/Session/Middleware.php b/src/Illuminate/Session/Middleware.php index c7d74473..57478b29 100644 --- a/src/Illuminate/Session/Middleware.php +++ b/src/Illuminate/Session/Middleware.php @@ -60,10 +60,11 @@ public function handle(Request $request, $type = HttpKernelInterface::MAIN_REQUE $this->checkRequestForArraySessions($request); // Check if this request is coming either from API or from Oauth access token - $isAPIorOauthRequest = $request->headers->has('Authorization') || - ($request->isMethod('POST') && str_contains($request->getUri(), 'api/v1/oauth/')) || - str_contains($request->getUri(), '/api/'); - + $currentPath = $request->getRequestUri(); + $authorizationHeader = $request->headers->get('Authorization'); + $isFromTokenBasedAuthentication = + (!empty($authorizationHeader) && preg_match("/(Basic|Bearer) .+/", $authorizationHeader)) || + starts_with($currentPath, '/api/v1/oauth/'); // If a session driver has been configured, we will need to start the session here // so that the data is ready for an application. Note that the Laravel sessions @@ -71,7 +72,7 @@ public function handle(Request $request, $type = HttpKernelInterface::MAIN_REQUE // this api has been modified to prevent request from API starting the // session, and saving the session as we don't need user session here - if (!$isAPIorOauthRequest && $this->sessionConfigured()) + if (!$isFromTokenBasedAuthentication && $this->sessionConfigured()) { $session = $this->startSession($request); @@ -86,7 +87,7 @@ public function handle(Request $request, $type = HttpKernelInterface::MAIN_REQUE // this api has been modified to prevent request from API starting the // session, and saving the session as we don't need user at backend side here - if (!$isAPIorOauthRequest && $this->sessionConfigured()) + if (!$isFromTokenBasedAuthentication && $this->sessionConfigured()) { $this->storeCurrentUrl($request, $session); $this->closeSession($session); From 83fdddf944d9ba6a7c9f6db450ee649d5a3a6d70 Mon Sep 17 00:00:00 2001 From: AlexzPurewoko Date: Thu, 28 Aug 2025 14:27:39 +0700 Subject: [PATCH 4/5] tidying up: convert it to external method --- src/Illuminate/Session/Middleware.php | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/Illuminate/Session/Middleware.php b/src/Illuminate/Session/Middleware.php index 57478b29..260fde41 100644 --- a/src/Illuminate/Session/Middleware.php +++ b/src/Illuminate/Session/Middleware.php @@ -59,12 +59,8 @@ public function handle(Request $request, $type = HttpKernelInterface::MAIN_REQUE { $this->checkRequestForArraySessions($request); - // Check if this request is coming either from API or from Oauth access token - $currentPath = $request->getRequestUri(); - $authorizationHeader = $request->headers->get('Authorization'); - $isFromTokenBasedAuthentication = - (!empty($authorizationHeader) && preg_match("/(Basic|Bearer) .+/", $authorizationHeader)) || - starts_with($currentPath, '/api/v1/oauth/'); + // Check if this request is coming from web based auth + $isFromWebBasedAuth = $this->isRequestFromWebBasedAuth($request); // If a session driver has been configured, we will need to start the session here // so that the data is ready for an application. Note that the Laravel sessions @@ -72,7 +68,7 @@ public function handle(Request $request, $type = HttpKernelInterface::MAIN_REQUE // this api has been modified to prevent request from API starting the // session, and saving the session as we don't need user session here - if (!$isFromTokenBasedAuthentication && $this->sessionConfigured()) + if ($isFromWebBasedAuth && $this->sessionConfigured()) { $session = $this->startSession($request); @@ -87,7 +83,7 @@ public function handle(Request $request, $type = HttpKernelInterface::MAIN_REQUE // this api has been modified to prevent request from API starting the // session, and saving the session as we don't need user at backend side here - if (!$isFromTokenBasedAuthentication && $this->sessionConfigured()) + if ($isFromWebBasedAuth && $this->sessionConfigured()) { $this->storeCurrentUrl($request, $session); $this->closeSession($session); @@ -98,6 +94,17 @@ public function handle(Request $request, $type = HttpKernelInterface::MAIN_REQUE return $response; } + private function isRequestFromWebBasedAuth(Request $request): bool + { + $currentPath = $request->getRequestUri(); + $authorizationHeader = $request->headers->get('Authorization'); + $isFromTokenBasedAuthentication = + (!empty($authorizationHeader) && preg_match("/(Basic|Bearer) .+/", $authorizationHeader)) || + starts_with($currentPath, '/api/v1/oauth/'); + + return !$isFromTokenBasedAuthentication; + } + /** * Check the request and reject callback for array sessions. * From fddad07b2925ed2b2997cd934dfe20e0ca1a4d6f Mon Sep 17 00:00:00 2001 From: AlexzPurewoko Date: Thu, 28 Aug 2025 15:18:43 +0700 Subject: [PATCH 5/5] adding the test to case when session is not used --- tests/Session/SessionMiddlewareTest.php | 60 +++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/tests/Session/SessionMiddlewareTest.php b/tests/Session/SessionMiddlewareTest.php index 0cac3622..ff119724 100644 --- a/tests/Session/SessionMiddlewareTest.php +++ b/tests/Session/SessionMiddlewareTest.php @@ -69,6 +69,66 @@ public function testSessionIsNotUsedWhenNoDriver() $this->assertSame($response, $middleResponse); } + public function testSessionIsNotUsedWhenRequestHasValidAuthorizationHeader(): void + { + $request = Symfony\Component\HttpFoundation\Request::create('http://www.foo.com/api/some-api', 'GET', server: [ + 'HTTP_AUTHORIZATION' => 'Bearer 1234567890', + ]); + $response = new Symfony\Component\HttpFoundation\Response; + + $middle = new Illuminate\Session\Middleware( + $app = m::mock(HttpKernelInterface::class), + $manager = m::mock(SessionManager::class) + ); + + $manager->shouldNotReceive('getSessionConfig'); + + $manager->shouldReceive('driver')->andReturn($driver = m::mock(Store::class)->makePartial()); + $driver->shouldNotReceive('setRequestOnHandler'); + $driver->shouldNotReceive('start'); + $app->shouldReceive('handle')->once()->with($request, Symfony\Component\HttpKernel\HttpKernelInterface::MAIN_REQUEST, true)->andReturn($response); + $driver->shouldNotReceive('save'); + $driver->shouldNotReceive('getHandler'); + $driver->shouldNotReceive('getName')->andReturn('name'); + $driver->shouldNotReceive('getId')->andReturn(1); + $driver->shouldNotReceive('setPreviousUrl'); + + $middleResponse = $middle->handle($request); + + self::assertSame($response, $middleResponse); + self::assertCount(0, $response->headers->getCookies()); + } + + + + public function testSessionIsNotUsedWhenRequestFromOauthApi(): void + { + $request = Symfony\Component\HttpFoundation\Request::create('http://www.foo.com/api/v1/oauth/token', 'POST'); + $response = new Symfony\Component\HttpFoundation\Response; + + $middle = new Illuminate\Session\Middleware( + $app = m::mock(HttpKernelInterface::class), + $manager = m::mock(SessionManager::class) + ); + + $manager->shouldNotReceive('getSessionConfig'); + + $manager->shouldReceive('driver')->andReturn($driver = m::mock(Store::class)->makePartial()); + $driver->shouldNotReceive('setRequestOnHandler'); + $driver->shouldNotReceive('start'); + $app->shouldReceive('handle')->once()->with($request, Symfony\Component\HttpKernel\HttpKernelInterface::MAIN_REQUEST, true)->andReturn($response); + $driver->shouldNotReceive('save'); + $driver->shouldNotReceive('getHandler'); + $driver->shouldNotReceive('getName')->andReturn('name'); + $driver->shouldNotReceive('getId')->andReturn(1); + $driver->shouldNotReceive('setPreviousUrl'); + + $middleResponse = $middle->handle($request); + + self::assertSame($response, $middleResponse); + self::assertCount(0, $response->headers->getCookies()); + } + public function testCheckingForRequestUsingArraySessions() {