JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
fix session idle timeout, change defaults
authorJason Woofenden <jason@jasonwoof.com>
Wed, 1 Apr 2015 20:18:05 +0000 (16:18 -0400)
committerJason Woofenden <jason@jasonwoof.com>
Wed, 1 Apr 2015 20:18:05 +0000 (16:18 -0400)
session.php

index 3b96e84..d75e07e 100644 (file)
@@ -57,14 +57,12 @@ function session_generate_key() {
        return $id;
 }
 
        return $id;
 }
 
-# start a new session.
-# by default it'll expire in 24 hours regardless of activity.
-# pass both args for a session that lasts longer if active.
-# sessions are tracked with a "session cookie" (dies on browser close)
-function session_new($idle_timeout = 86400, $max_timeout = 'same_as_idle') {
-       if ($max_timeout === 'same_as_idle') {
-               $max_timeout = $idle_timeout;
-       }
+# start a new session, tracked by a browser "session cookie".
+#
+# args:
+#    $idle_timeout (seconds) session ends after this much inactivity (or up to 10% less)
+#    $max_length (seconds) session ends after this long, regardless of activity
+function session_new($idle_timeout = 129600 /* 36 hours */, $max_length = 604800 /* 1 week */) {
        kill_session();
 
        $session_key = session_generate_key();
        kill_session();
 
        $session_key = session_generate_key();
@@ -74,7 +72,7 @@ function session_new($idle_timeout = 86400, $max_timeout = 'same_as_idle') {
                'session_key' => $session_key,
                'idle_timeout' => $idle_timeout,
                'expires' => $now + $idle_timeout,
                'session_key' => $session_key,
                'idle_timeout' => $idle_timeout,
                'expires' => $now + $idle_timeout,
-               'expires_max' => $now + $max_timeout,
+               'expires_max' => $now + $max_length,
                'value' => ''
        );
 
                'value' => ''
        );
 
@@ -84,9 +82,9 @@ function session_new($idle_timeout = 86400, $max_timeout = 'same_as_idle') {
                'exists' => true,
                'id' => $session_id,
                'key' => $session_key,
                'exists' => true,
                'id' => $session_id,
                'key' => $session_key,
-               'idle_timeout' => $row['idle_timeout'],
-               'expires' => $row['expires'],
-               'expires_max' => $row['expires_max'],
+               'idle_timeout' => $idle_timeout,
+               'expires' => $now + $idle_timeout,
+               'expires_max' => $now + $max_length,
                'value' => array()
        );
        session_set_cookie();
                'value' => array()
        );
        session_set_cookie();
@@ -111,13 +109,16 @@ function session_touch() {
        if ($GLOBALS['wfpl_session']['expires'] < $GLOBALS['wfpl_session']['expires_max']) {
                # would this extend the session by at least 10%?
                $now = time();
        if ($GLOBALS['wfpl_session']['expires'] < $GLOBALS['wfpl_session']['expires_max']) {
                # would this extend the session by at least 10%?
                $now = time();
-               $session_start = $GLOBALS['wfpl_session']['expires'] - $GLOBALS['wfpl_session']['idle_timeout'];
-               if ($now > $session_start + ceil(0.1 * $GLOBALS['wfpl_session']['idle_timeout'])) {
-                       $expires = max(
+               $last_activity = $GLOBALS['wfpl_session']['expires'] - $GLOBALS['wfpl_session']['idle_timeout'];
+               # don't db_update if only a tiny fraction of the idle timeout has passed
+               $db_threshold = ceil(0.1 * $GLOBALS['wfpl_session']['idle_timeout']);
+               if ($now > $last_activity + $db_threshold) {
+                       $expires = min(
                                $GLOBALS['wfpl_session']['expires_max'],
                                $now + $GLOBALS['wfpl_session']['idle_timeout']
                        );
                        db_update('wfpl_sessions', 'expires', $expires, 'where id=%i', $GLOBALS['wfpl_session']['id']);
                                $GLOBALS['wfpl_session']['expires_max'],
                                $now + $GLOBALS['wfpl_session']['idle_timeout']
                        );
                        db_update('wfpl_sessions', 'expires', $expires, 'where id=%i', $GLOBALS['wfpl_session']['id']);
+                       $GLOBALS['wfpl_session']['expires'] = $expires;
                }
        }
 }
                }
        }
 }
@@ -154,17 +155,21 @@ function session_exists() {
                return false;
        }
 
                return false;
        }
 
-       session_purge_old();
        $row = db_get_assoc('wfpl_sessions', 'id,idle_timeout,expires,expires_max,value', 'where session_key=%"', $session_key);
        if($row === false) {
                return false;
        }
        $row = db_get_assoc('wfpl_sessions', 'id,idle_timeout,expires,expires_max,value', 'where session_key=%"', $session_key);
        if($row === false) {
                return false;
        }
+       $now = time();
+       if ($now >= (int) $row['expires']) {
+               session_purge_old();
+               return false;
+       }
 
        $GLOBALS['wfpl_session']['exists'] = true;
        $GLOBALS['wfpl_session']['id'] = $row['id'];
 
        $GLOBALS['wfpl_session']['exists'] = true;
        $GLOBALS['wfpl_session']['id'] = $row['id'];
-       $GLOBALS['wfpl_session']['idle_timeout'] = $row['idle_timeout'];
-       $GLOBALS['wfpl_session']['expires'] = $row['expires'];
-       $GLOBALS['wfpl_session']['expires_max'] = $row['expires_max'];
+       $GLOBALS['wfpl_session']['idle_timeout'] = (int) $row['idle_timeout'];
+       $GLOBALS['wfpl_session']['expires'] = (int) $row['expires'];
+       $GLOBALS['wfpl_session']['expires_max'] = (int) $row['expires_max'];
        $GLOBALS['wfpl_session']['key'] = $session_key;
 
        if (strlen($row['value']) && is_array($parsed = json_decode($row['value'], true))) {
        $GLOBALS['wfpl_session']['key'] = $session_key;
 
        if (strlen($row['value']) && is_array($parsed = json_decode($row['value'], true))) {