bug #36118 [Security/Http] don't require the session to be started when tracking its id (nicolas-grekas)

This PR was merged into the 4.4 branch.

Discussion
----------

[Security/Http] don't require the session to be started when tracking its id

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | -
| License       | MIT
| Doc PR        | -

`$session->getId()` returns the empty string when the session is not yet started.
When this happens, the session tracking logic wrongly detects that a new session was created and thus disables HTTP caching.

This fixes the issue by looking at the value of the session cookie instead.
(the case for `true` is when using `MockArraySessionStorage` as done in tests)

Commits
-------

c39188a7cc [Security/Http] don't require the session to be started when tracking its id
This commit is contained in:
Fabien Potencier 2020-03-18 08:28:07 +01:00
commit abefccfbe9
2 changed files with 22 additions and 2 deletions

View File

@ -115,10 +115,10 @@ class ContextListener extends AbstractListener implements ListenerInterface
if (null !== $session) {
$usageIndexValue = method_exists(Request::class, 'getPreferredFormat') && $session instanceof Session ? $usageIndexReference = &$session->getUsageIndex() : 0;
$sessionId = $session->getId();
$sessionId = $request->cookies->get($session->getName());
$token = $session->get($this->sessionKey);
if ($this->sessionTrackerEnabler && $session->getId() === $sessionId) {
if ($this->sessionTrackerEnabler && \in_array($sessionId, [true, $session->getId()], true)) {
$usageIndexReference = $usageIndexValue;
}
}

View File

@ -344,6 +344,26 @@ class ContextListenerTest extends TestCase
$this->assertNull($tokenStorage->getToken());
}
/**
* @requires function \Symfony\Component\HttpFoundation\Request::getPreferredFormat
*/
public function testWithPreviousNotStartedSession()
{
$session = new Session(new MockArraySessionStorage());
$request = new Request();
$request->setSession($session);
$request->cookies->set('MOCKSESSID', true);
$usageIndex = $session->getUsageIndex();
$tokenStorage = new TokenStorage();
$listener = new ContextListener($tokenStorage, [], 'context_key', null, null, null, [$tokenStorage, 'getToken']);
$listener(new RequestEvent($this->getMockBuilder(HttpKernelInterface::class)->getMock(), $request, HttpKernelInterface::MASTER_REQUEST));
$this->assertSame($usageIndex, $session->getUsageIndex());
}
protected function runSessionOnKernelResponse($newToken, $original = null)
{
$session = new Session(new MockArraySessionStorage());