Skip to content

broken session cache limiter settings in config options #2283

Description

@Jehfen

Not to be disrespectfull, but the session cache limiter settings in config options (see below) is dense and not very intuitive, and shouldn't default to an aggressive setting.
Without knowing, it rendered new selector-fetched pages invisible to guest users and enabled previously saved session cookie preferences from being ignored completely. I took me half a day to figure out whether is was nginx, fastcgi, htaccess or any other setting that was causing the caching problems.

In future versions please set 'false' as default, and provide easier or more comprehensive options to be selectable.

Applies to GET or HEAD requests only.
Note: prior to 3.0.258, ProcessWire did not set any cache limiter, deferring entirely to PHP’s default. If your site relies on the previous behavior, set $config->sessionCacheLimiter = false.
In 3.0.265+ if the user is guest and the cache limiter is private_no_expire then ProcessWire will downgrade the Cache-Control header to no-cache if any session variables are set during page rendering. This is to prevent caching of pages that might be rendering forms with CSRF or other session variables that could affect the output. Configuration options:
1) Associative array of setting to use, indexed by context, i.e. ~ $config->sessionCacheLimiter = [ 'guest' => 'private_no_expire', 'admin' => 'nocache', 'loggedin' => 'nocache', ];
~ 2) Boolean false to prevent ProcessWire from using the session cache limiter (for behavior prior to 3.0.258); ~ $config->sessionCacheLimiter = false;
~ 3) A callable which receives a string $context argument containing 'guest', 'loggedin' or 'admin' and it should return a string one of the "allowed values" below, or an array containing http headers you want to send. When specifying http headers, it should be an associative array like: [ 'header-name' => 'header-value' ] ~ $config->sessionCacheLimiter = function($context) { if($context === 'guest') return [ // headers example 'Cache-Control' => 'no-store, no-cache, must-revalidate', 'Expires' => 'Thu, 19 Nov 1981 08:52:00 GMT', ];
return 'nocache';
}; ~ Contexts:
- guest: Applies to non-logged in users that are not in an admin URL.
- admin: Applies to anything in the admin, including login page before logged-in.
- loggedin: Applies to users that are currently (or recently were) logged in.
Please note that the loggedin context used when a login cookie is present, and does not always guarantee a user is currently logged in. That's because cache control headers must be sent before the session is started (and before we know whether a user is actually logged in). Allowed values (choose one for each context): - nocache: Disallows any client/proxy caching by sending headers like Cache-Control: no-store, no-cache, must-revalidate and an Expires header with a date in the past.
- private: Disallows caching by proxies but permits the client (browser) to cache the content. The Expires header is sent to the client in this mode.
- private_no_expire: Similar to private, but the Expires header is never sent to the client. This avoids potential confusion for some browsers.
Note: caching options like private_no_expire, private, and public permit HTTP 304 responses. If your site uses per-request dynamic response headers (such as CSP nonces), a 304 response will send new headers while the browser reuses cached HTML — causing a mismatch. In that case, use a callable to prevent conditional requests while preserving bfcache:
~ $config->sessionCacheLimiter = [ 'guest' => function() { header_remove('ETag');
header_remove('Last-Modified');
return ['Cache-Control' => 'private, max-age=0, must-revalidate'];
}, 'loggedin' => 'nocache', 'admin' => 'nocache', ];
~ This preserves browser back/forward cache (bfcache) while ensuring the browser always fetches a full 200 response rather than a 304.
- public: Permits caching by both proxies and the client.
- none: Prevent PHP and ProcessWire from sending any cache headers. - false (bool): Use the session_cache_limiter setting defined in the php.ini. - You may optionally use an array with the headers you want to be sent, i.e. ~ $config->sessionCacheLimiter = [ 'guest' => [ 'Cache-Control' => 'no-store, no-cache, must-revalidate', 'Expires' => 'Thu, 19 Nov 1981 08:52:00 GMT', 'Pragma' => 'no-cache', ], 'loggedin' => 'nocache', 'admin' => 'nocache', ];
~ - You may optionally use a callable that returns the cache setting (nocache, private, etc.) or returns an array of http headers, like described above.
~ $config->sessionCacheLimiter = [ 'guest' => function() { if(strpos($_SERVER['REQUEST_URI'], '/products/') !== false) { return 'nocache';
} else { return 'private_no_expire';
} }, 'loggedin' => 'nocache', 'admin' => 'nocache', ];

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions