Requests that start a session should not be allowed to be cached in page cache

Created on 5 January 2017, almost 8 years ago
Updated 4 December 2024, 14 days ago

Problem/Motivation

I've been tracking down a bug that happen on a custom page that set some session variables but ended up being cached.

The result was that later users then mananged to get to that page (it's part of a multi-step process) without the session being initialized, leading to errors on the next page.

Pretty sure this is the same in 7.x.

Proposed resolution

Do not treat a page with session data as cacheable?

Remaining tasks

User interface changes

API changes

Data model changes

🐛 Bug report
Status

Needs work

Version

11.0 🔥

Component

page_cache.module

Created by

🇨🇭Switzerland berdir Switzerland

Live updates comments and jobs are added and updated live.
  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

  • Needs issue summary update

    Issue summaries save everyone time if they are kept up-to-date. See Update issue summary task instructions.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇨🇭Switzerland znerol

    I've been tracking down a bug that happen on a custom page that set some session variables but ended up being cached.

    I guess this custom page violates HTTP idempotency. In short, a GET or HEAD request should not modify data on the server.

    The page cache module assumes that developers respect this principle. I.e., it assumes that GET and HEAD requests do not modify data and as a consequence do not try to set session values.

    In order to modify data (even if its only session data), you need to use POST.

  • 🇨🇭Switzerland znerol

    To expand a little bit on the explanation above. Drupal in fact allows you to opt out of caching on specific routes using the no_cache route option. An example of such a route is system.cron in system.routing.yml.

    system.cron:
      path: '/cron/{key}'
      defaults:
        _controller: '\Drupal\system\CronController::run'
      options:
        no_cache: TRUE
      requirements:
        _access_system_cron: 'TRUE'
    

    This is also a really good example for a reasonable exception to the HTTP idempotency rule.

    I suggest to close this issue (works as designed).

Production build 0.71.5 2024