jenssegers / laravel-mongodb-session

A MongoDB session driver for Laravel
77 stars 27 forks source link

Session lifetime is using Seconds (not minutes) #17

Open george-viaud opened 7 years ago

george-viaud commented 7 years ago

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 ?

SimplyCorey commented 6 years ago

I'm having the same issue.

SimplyCorey commented 6 years ago

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.

xiaodong-zhu commented 6 years ago

same issue here. modify php.ini works.

MightyPork commented 4 years ago

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

tonivega commented 2 years ago

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.