diff --git a/docs/book/v1/manual.md b/docs/book/v1/manual.md
index 43bfdbb..7e1030a 100644
--- a/docs/book/v1/manual.md
+++ b/docs/book/v1/manual.md
@@ -36,7 +36,10 @@ The following details the constructor of the `Mezzio\Session\Cache\CacheSessionP
* @param string $cookieSameSite The same-site rule to apply to the persisted
* cookie. Options include "Lax", "Strict", and "None".
* Available since 1.4.0
- *
+ * @param bool $autoRegenerate Whether or not the session ID should be
+ * regenerated on session data changes
+ * Available since 1.13.0
+ *
* @todo reorder these arguments so they make more sense and are in an
* order of importance
*/
@@ -51,7 +54,8 @@ public function __construct(
string $cookieDomain = null,
bool $cookieSecure = false,
bool $cookieHttpOnly = false,
- string $cookieSameSite = 'Lax'
+ string $cookieSameSite = 'Lax',
+ bool $autoRegenerate = true,
) {
```
diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index 3c353c0..4d68d07 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -22,13 +22,10 @@
$cacheService
get($cacheService)]]>
$cookieDomain
- $cookieHttpOnly
$cookieName
$cookiePath
$cookieSameSite
- $cookieSecure
$lastModified
- $persistent
@@ -43,6 +40,7 @@
+
$cacheExpire
@@ -58,6 +56,7 @@
$cookieSecure
$lastModified
$persistent
+ $autoRegenerate
diff --git a/src/CacheSessionPersistence.php b/src/CacheSessionPersistence.php
index 66f81ad..13f3c27 100644
--- a/src/CacheSessionPersistence.php
+++ b/src/CacheSessionPersistence.php
@@ -34,6 +34,7 @@ class CacheSessionPersistence implements SessionPersistenceInterface
private CacheItemPoolInterface $cache;
private bool $persistent;
+ private bool $autoRegenerate;
/**
* Prepare session cache and default HTTP caching headers.
@@ -67,6 +68,8 @@ class CacheSessionPersistence implements SessionPersistenceInterface
* be accessed by client-side apis.
* @param string $cookieSameSite The same-site rule to apply to the persisted
* cookie. Options include "Lax", "Strict", and "None".
+ * @param bool $autoRegenerate Whether or not the session ID should be
+ * regenerated on session data changes
* @todo reorder the constructor arguments
*/
public function __construct(
@@ -80,7 +83,8 @@ public function __construct(
?string $cookieDomain = null,
bool $cookieSecure = false,
bool $cookieHttpOnly = false,
- string $cookieSameSite = 'Lax'
+ string $cookieSameSite = 'Lax',
+ bool $autoRegenerate = true
) {
$this->cache = $cache;
@@ -112,6 +116,8 @@ public function __construct(
: $this->getLastModified();
$this->persistent = $persistent;
+
+ $this->autoRegenerate = $autoRegenerate;
}
public function initializeSessionFromRequest(ServerRequestInterface $request): SessionInterface
@@ -139,8 +145,8 @@ public function persistSession(SessionInterface $session, ResponseInterface $res
// Regenerate the session if:
// - we have no session identifier
// - the session is marked as regenerated
- // - the session has changed (data is different)
- if ('' === $id || $session->isRegenerated() || $session->hasChanged()) {
+ // - the session has changed (data is different) and autoRegenerate is turned on (default) in the configuration
+ if ('' === $id || $session->isRegenerated() || ($this->autoRegenerate && $session->hasChanged())) {
$id = $this->regenerateSession($id);
}
diff --git a/src/CacheSessionPersistenceFactory.php b/src/CacheSessionPersistenceFactory.php
index 65a9e4c..b2e4654 100644
--- a/src/CacheSessionPersistenceFactory.php
+++ b/src/CacheSessionPersistenceFactory.php
@@ -34,6 +34,7 @@ public function __invoke(ContainerInterface $container)
$cacheExpire = $config['cache_expire'] ?? 10800;
$lastModified = $config['last_modified'] ?? null;
$persistent = $config['persistent'] ?? false;
+ $autoRegenerate = $config['auto_regenerate'] ?? true;
return new CacheSessionPersistence(
$container->get($cacheService),
@@ -42,11 +43,12 @@ public function __invoke(ContainerInterface $container)
$cacheLimiter,
$cacheExpire,
$lastModified,
- $persistent,
+ (bool) $persistent,
$cookieDomain,
- $cookieSecure,
- $cookieHttpOnly,
- $cookieSameSite
+ (bool) $cookieSecure,
+ (bool) $cookieHttpOnly,
+ $cookieSameSite,
+ (bool) $autoRegenerate
);
}
}
diff --git a/test/CacheSessionPersistenceFactoryTest.php b/test/CacheSessionPersistenceFactoryTest.php
index b288b65..96c675c 100644
--- a/test/CacheSessionPersistenceFactoryTest.php
+++ b/test/CacheSessionPersistenceFactoryTest.php
@@ -74,6 +74,7 @@ public function testFactoryUsesSaneDefaultsForConstructorArguments(): void
$this->assertAttributeSame(10800, 'cacheExpire', $persistence);
$this->assertAttributeNotEmpty('lastModified', $persistence);
$this->assertAttributeSame(false, 'persistent', $persistence);
+ $this->assertAttributeSame(true, 'autoRegenerate', $persistence);
}
public function testFactoryAllowsConfiguringAllConstructorArguments(): void
@@ -95,6 +96,7 @@ public function testFactoryAllowsConfiguringAllConstructorArguments(): void
'cache_expire' => 300,
'last_modified' => $lastModified,
'persistent' => true,
+ 'auto_regenerate' => false,
],
]);
@@ -115,6 +117,7 @@ public function testFactoryAllowsConfiguringAllConstructorArguments(): void
$persistence
);
$this->assertAttributeSame(true, 'persistent', $persistence);
+ $this->assertAttributeSame(false, 'autoRegenerate', $persistence);
}
public function testFactoryAllowsConfiguringCacheAdapterServiceName(): void
diff --git a/test/CacheSessionPersistenceIntegrationTest.php b/test/CacheSessionPersistenceIntegrationTest.php
index da85037..e56b491 100644
--- a/test/CacheSessionPersistenceIntegrationTest.php
+++ b/test/CacheSessionPersistenceIntegrationTest.php
@@ -111,4 +111,40 @@ public function testThatAChangedSessionWillCauseRegenerationAndASetCookieHeader(
$value = $item->get();
self::assertNull($value, 'The previous session data should have been deleted');
}
+
+ public function testThatAChangedSessionWillNotCauseRegenerationWhenAutoRegenerateIsFalse(): void
+ {
+ $this->storage = new CacheSessionPersistence(
+ $this->cache,
+ cookieName: 'Session',
+ autoRegenerate: false,
+ );
+
+ $item = $this->cache->getItem('foo');
+ $item->set(['foo' => 'bar']);
+ $this->cache->save($item);
+
+ $request = (new ServerRequest())->withHeader('Cookie', 'Session=foo;');
+ $middleware = new SessionMiddleware($this->storage);
+ $handler = new TestHandler();
+ $handler->setSessionVariable('something', 'groovy');
+ $response = $middleware->process($request, $handler);
+
+ $setCookie = SetCookies::fromResponse($response);
+ $cookie = $setCookie->get('Session');
+ self::assertNotNull($cookie);
+
+ $id = $cookie->getValue();
+ self::assertNotNull($id);
+
+ self::assertSame('foo', $id);
+ self::assertNotSame($handler->response, $response);
+
+ $item = $this->cache->getItem('foo');
+ $value = $item->get();
+ self::assertSame([
+ 'foo' => 'bar',
+ 'something' => 'groovy',
+ ], $value, 'The session data should have been updated');
+ }
}