diff --git a/web/includes/session.php b/web/includes/session.php index 9d99e0333..52a05011b 100644 --- a/web/includes/session.php +++ b/web/includes/session.php @@ -40,6 +40,26 @@ function zm_setcookie($cookie, $value, $options=array()) { //ZM\Debug("Setting cookie for $cookie to $value"); } +// A session is only worth storing if the client actually carries it. A request +// that arrives without our cookie - a bot, an image tag or a cross-origin ajax +// poll authenticated by auth hash or token - still gets a session for the life +// of the request, but writing it out leaves a Sessions row that nothing will +// ever load again. Viewing an event polls the event's server every +// ZM_WEB_REFRESH_STATUS seconds, so a cross-origin poll used to add a row every +// few seconds. Login is the exception: that is where a session is first issued. +$zm_session_persist = false; + +// Store this session even though the client arrived without our cookie. +function zm_session_persist() { + global $zm_session_persist; + $zm_session_persist = true; +} + +function zm_session_is_persistable() { + global $zm_session_persist; + return $zm_session_persist || !empty($_COOKIE[session_name()]); +} + // ZM session start function support timestamp management function zm_session_start() { if (ini_get('session.name') != 'ZMSESSID') { @@ -115,6 +135,8 @@ function zm_session_regenerate_id() { // Assumes zm_session_start() has been called previously. function zm_session_regenerate_id_login() { if (!is_session_started()) zm_session_start(); + // The client has no cookie yet on a first login, but this session must be stored. + zm_session_persist(); // Discard any pre-auth session contents so nothing carries across the // authentication boundary. $_SESSION = array(); @@ -190,6 +212,7 @@ class ZMSessionHandler implements SessionHandlerInterface { return ''; } public function write($id, $data) : bool { + if (!zm_session_is_persistable()) return true; if (!($db = zmDbConnOrNull())) return false; // Create time stamp $access = time(); diff --git a/web/index.php b/web/index.php index 2ab6b0925..9b5a9e8f9 100644 --- a/web/index.php +++ b/web/index.php @@ -263,6 +263,7 @@ if ( ZM_OPT_USE_AUTH and (!isset($user) or !($user instanceof ZM\User)) and ($vi $postLoginQuery = $_SERVER['QUERY_STRING']; $redirect = '?view=login'.($postLoginQuery?'&postLoginQuery=' . urlencode($postLoginQuery):''); zm_session_start(); + zm_session_persist(); // must survive the redirect even if the client had no cookie $_SESSION['postLoginQuery'] = $postLoginQuery; session_write_close(); ZM\Debug("Redirecting to $redirect");