Skip to content

SessionMiddleware

Bootstrap-phase session wiring for the framework pipeline.

Loads or creates this request’s session, installs it as the context’s SessionBagInterface so every consumer — the User hierarchy, CSRF token storage, OIDC state, application code — reaches the same session, persists the user before the session is written, and bakes the Set-Cookie onto the response.

With no session factory slot configured there is no session to manage: Context::getSessionBag() keeps answering a NullSessionBag, and this middleware does nothing beyond ensuring an ExecutionState exists. That is the shape a console command, a queue worker or a stateless API runs in.

Distinct from SessionMiddleware, which is the standalone PSR-15 wiring for an application driving SessionManager outside this pipeline. This one additionally owns the ExecutionState guarantee and the request-state flush, both of which are pipeline concerns.

class SessionMiddleware implements MiddlewareInterface

ImplementsMiddlewareInterface
SourceMiddleware/SessionMiddleware.php

public function __construct(Controller $controller): mixed

ParameterTypeDescription
$controllerController

Returns mixed

MethodDescription
process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterfaceStarts the request’s session, exposes it to the context, and bakes the cookie onto the response.

public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface

Starts the request’s session, exposes it to the context, and bakes the cookie onto the response.

Guarantees an ExecutionState attribute on the request first. A request flagged sessionless — by auth.sessionless, or by the equivalent jwt.skip_session, both honoured — and a context with no SessionManager bound skip session handling entirely: the request passes through and the request-state flush is claimed with persistUser: false, so a token-derived identity is never written into whatever unrelated session the client may still carry.

Otherwise the session is started from the request and published as the container’s request-scoped SessionBagInterface, so the user hierarchy, CSRF storage and application code all reach the same session. After the downstream handler returns — including when it throws — the request state is flushed so the user is written before the session is persisted; a failing flush is logged at debug and does not stop the response. The returned response is the one produced by persisting the session and baking its Set-Cookie.

ParameterTypeDescription
$requestServerRequestInterface
$handlerRequestHandlerInterface

Returns ResponseInterface