Problem/Motivation

Persistent workers such as FrankenPHP worker mode can reuse the session_manager service across requests. SessionManager::destroy() calls session_destroy() but leaves started set to TRUE and closed set to FALSE. On the next request, SessionManager::start() returns early: it does not apply the new request's session options, reinitialize $_SESSION, or reattach the session bags. NativeSessionStorage::start() also returns early because started is TRUE, so session_start() never runs. This silently breaks logging in.

Steps to reproduce

  1. Start a session using an incoming session cookie.
  2. Destroy the session directly, or leave it empty and save it to trigger obsolete-session destruction.
  3. Unset $_SESSION and reuse the same session storage for another request.
  4. Start the session, set a value, and save it.

Expected: after step 2, isStarted() returns FALSE. In step 4, the value is written through the session handler.

Actual: after step 2, isStarted() returns TRUE although no PHP session is active. In step 4, the value is not written to $_SESSION and the handler's write() is never called.

Proposed resolution

After session_destroy(), set started and startedLazy to FALSE and closed to TRUE. started and closed match the state NativeSessionStorage::save() leaves after closing a session. startedLazy is Drupal's own flag and must also be reset.

User interface changes

None.

API changes

None.

Data model changes

None.

AI disclosure: I used AI to help prepare the IS and MR (Astra and Opus 5.5).

Issue fork drupal-3626371

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

ptmkenny created an issue. See original summary.

ptmkenny’s picture

Category: Feature request » Bug report

ptmkenny’s picture

Status: Active » Needs review