Closed
Description
Symfony version(s) affected: 4.4.0
Description
Option gc_maxlifetime
doesn't work well, because RedisSessionHandler use a different variable for this purpose.
session.gc_maxlifetime
will set on setOptions
method of Session/Storage/NativeSessionStorage
called on ___construct
method, but Session/Storage/Handler/RedisSessionHandler
set ttl
property on his __construct
, called before NativeSessionStorage::__construct
.
How to reproduce
use Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
ini_set('session.gc_maxlifetime', 60); // set session.gc_maxlifetime to 60
$handler = new RedisSessionHandler($predis); // $this->ttl = 60;
$storage = new NativeSessionStorage(['gc_maxlifetime' => 360], $handler); // set session.gc_maxlifetime = 360
$session = new Session($storage);
$session->start();
$session->set('uid', 1); // set expire on redis to 60
Possible Solution
// Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler;
class RedisSessionHandler extends AbstractSessionHandler
{
private $redis;
/**
* @var string Key prefix for shared environments
*/
private $prefix;
/**
* @var int Time to live in seconds
*/
private $ttl;
/**
* List of available options:
* * prefix: The prefix to use for the keys in order to avoid collision on the Redis server
* * ttl: The time to live in seconds.
*
* @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|RedisProxy|RedisClusterProxy $redis
*
* @throws \InvalidArgumentException When unsupported client or options are passed
*/
public function __construct($redis, array $options = [])
{
//...
$this->redis = $redis;
$this->prefix = $options['prefix'] ?? 'sf_s';
// $this->ttl = $options['ttl'] ?? (int) ini_get('session.gc_maxlifetime');
$this->ttl = $options['ttl'] ?? 0;
}
// ...
/**
* {@inheritdoc}
*/
protected function doWrite($sessionId, $data): bool
{
$ttl = $this->ttl > 0? $this->ttl : (int) ini_get('session.gc_maxlifetime');
$result = $this->redis->setEx($this->prefix.$sessionId, $ttl, $data);
return $result && !$result instanceof ErrorInterface;
}
// ...
}