Refresh the session cookie only once it aged a bit
authorTim Düsterhus <duesterhus@woltlab.com>
Wed, 16 Dec 2020 11:42:20 +0000 (12:42 +0100)
committerTim Düsterhus <duesterhus@woltlab.com>
Wed, 6 Jan 2021 11:20:08 +0000 (12:20 +0100)
Resolves #3611

wcfsetup/install/files/lib/system/session/SessionHandler.class.php

index 5d26472f9f70d2f52c4db47f62da37af814c11ef..d779f48ca248c62efffaeeeb8c84bf3d7e5d6b70 100644 (file)
@@ -333,7 +333,6 @@ final class SessionHandler extends SingletonFactory {
                        $hasSession = $this->getExistingSession($sessionID);
                }
                
-               // create new session
                if (!$hasSession) {
                        $this->create();
                }
@@ -350,12 +349,41 @@ final class SessionHandler extends SingletonFactory {
                        $hasSession = $this->getExistingSession($sessionID);
                }
                
-               // create new session
-               if (!$hasSession) {
+               if ($hasSession) {
+                       $this->maybeRefreshCookie();
+               }
+               else {
                        $this->create();
                }
        }
        
+       /**
+        * Refreshes the session cookie, extending the expiry.
+        */
+       private function maybeRefreshCookie(): void {
+               // Guests and ACP use short-lived sessions with an actual
+               // session cookie.
+               if (!$this->user->userID) return;
+               if ($this->isACP) return;
+               
+               $cookieData = $this->getParsedCookieData();
+               
+               // No refresh is needed if userId and timestep match up.
+               if (
+                       $cookieData['userId'] === $this->user->userID &&
+                       $cookieData['timestep'] === $this->getCookieTimestep()
+               ) {
+                       return;
+               }
+               
+               // Refresh the cookie.
+               HeaderUtil::setCookie(
+                       ($this->isACP ? 'acp' : 'user') . '_session',
+                       $this->getCookieValue(),
+                       TIME_NOW + (self::USER_SESSION_LIFETIME * 2)
+               );
+       }
+       
        /**
         * Initializes session system.
         */
@@ -573,15 +601,6 @@ final class SessionHandler extends SingletonFactory {
                        $this->sessionID,
                ]);
                
-               // Refresh cookie.
-               if ($this->user->userID && !$this->isACP) {
-                       HeaderUtil::setCookie(
-                               ($this->isACP ? 'acp' : 'user') . '_session',
-                               $this->getCookieValue(),
-                               TIME_NOW + 86400 * 14
-                       );
-               }
-               
                // Fetch legacy session.
                if (!$this->isACP) {
                        $condition = new PreparedStatementConditionBuilder();