laravel-mongodb-session icon indicating copy to clipboard operation
laravel-mongodb-session copied to clipboard

Session lifetime is using Seconds (not minutes)

Open george-viaud opened this issue 7 years ago • 5 comments

I just ran into an issue w/ session lifetime.

session.php specifies the value in minutes (I have it set to 1440 which should be 24 hours).

However, in checking the session collection in the DB I find it to be setting expiration 24 minutes from the time last accessed.

Example from my sessions table:

    "last_activity" : ISODate("2017-07-19T17:03:41.000Z"),
    "expires_at" : ISODate("2017-07-19T17:27:41.000Z"),

Delta is 24 minutes exactly - (should be 24 hours in my case)

Anyone else experiencing this?

UPDATE: Changing the session.php lifetime value to 60, clearing the cache and removing all records from the sessions collection in the DB (and the logging back in) has NO EFFECT(session still timeout in 24 minutes and the DB session collection indicates the same)... This indicates that the lifetime value in the session.php file is not being used, but some 24 minute value elsewhere is being used? Perhaps gc_maxlifetime? Any thoughts on this?

UPDATE: Changing php.ini to reflect: session.gc_maxlifetime = 86400 (and then restarting apache2) seems to have done what I wanted but I'm not sure why this value is being used.

Also, I'm not sure I want the cleanup set to this long a period for PHP... Anyone have any idea why this value is being used by mongodb session driver and not the session.php lifetime ?

george-viaud avatar Jul 19 '17 17:07 george-viaud

I'm having the same issue.

SimplyCorey avatar Nov 29 '17 20:11 SimplyCorey

This is coming upstream from https://github.com/symfony/http-foundation/blob/master/Session/Storage/Handler/MongoDbSessionHandler.php#L120

It seems to be hardcoded and not adjustable.

SimplyCorey avatar Nov 30 '17 15:11 SimplyCorey

same issue here. modify php.ini works.

xiaodong-zhu avatar Mar 13 '18 08:03 xiaodong-zhu

Here is a patch for this bug I use:

When using mongodb as a session backend, the symfony driver uses hardcoded expiry time from php.ini.
This patch makes it accept an expiration time (seconds) as 'expiretime' in its options array.

--- vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php.orig	2020-03-13 12:55:28.000000000 +0100
+++ vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php	2020-03-13 13:24:19.223045994 +0100
@@ -88,6 +88,7 @@
             'data_field' => 'data',
             'time_field' => 'time',
             'expiry_field' => 'expires_at',
+             'expiretime' => (int) ini_get('session.gc_maxlifetime'),
         ], $options);
     }

@@ -132,7 +133,7 @@
      */
     protected function doWrite($sessionId, $data)
     {
-        $expiry = $this->createDateTime(time() + (int) ini_get('session.gc_maxlifetime'));
+        $expiry = $this->createDateTime(time() + (int) $this->options['expiretime']);

         $fields = [
             $this->options['time_field'] => $this->createDateTime(),
@@ -164,7 +165,7 @@
      */
     public function updateTimestamp($sessionId, $data)
     {
-        $expiry = $this->createDateTime(time() + (int) ini_get('session.gc_maxlifetime'));
+        $expiry = $this->createDateTime(time() + (int) $this->options['expiretime']);

         if ($this->mongo instanceof \MongoDB\Client) {
             $methodName = 'updateOne';
--- vendor/jenssegers/mongodb-session/src/Jenssegers/Mongodb/Session/SessionManager.php.orig	2018-01-08 11:44:00.000000000 +0100
+++ vendor/jenssegers/mongodb-session/src/Jenssegers/Mongodb/Session/SessionManager.php	2020-03-13 13:25:52.324982735 +0100
@@ -63,7 +63,14 @@
      */
     protected function getMongoDBOptions($database, $collection)
     {
-        return ['database' => $database, 'collection' => $collection, 'id_field' => '_id', 'data_field' => 'payload', 'time_field' => 'last_activity'];
+        return [
+            'database' => $database,
+            'collection' => $collection,
+            'id_field' => '_id',
+            'data_field' => 'payload',
+            'time_field' => 'last_activity',
+            'expiretime' => config('session.lifetime') * 60, // minutes to seconds
+        ];
     }

     /**

apply with patch -p0 -N -i fix_expiry.patch in project root

MightyPork avatar Mar 13 '20 13:03 MightyPork

As workaround without monkey patching it to set the ini value in AppServiceProvider->boot();

public function boot() { ini_set('session.gc_maxlifetime', 7*24*60*60); }

Note that the specified lifetime are seconds and not minutes.

tonivega avatar May 30 '22 02:05 tonivega