Problem
When FastAPICacheXSessionMiddleware sends a token (a new session, a sliding renewal, or a regenerated ID) it adds nothing that stops a shared cache from storing it. Vary is only added when the handler touched request.session (middleware.py, if session.accessed), and no Cache-Control is set.
On a @cache(ttl=60, public=True) route, a request that happens to trigger sliding renewal gets:
Cache-Control: public, max-age=60
Vary: (none)
Set-Cookie: session=fa632cf2-...; path=/; Max-Age=1209600; httponly; samesite=lax
A CDN or reverse proxy that stores responses with Set-Cookie will hand that cookie, which is a valid session token, to the next visitors. With header transport the token is in X-Session-Token, which proxies do not treat specially at all. With the default sliding_threshold=0.5 this happens on any request in the second half of a session's TTL.
#168 fixed which header name goes in Vary; it did not cover responses where the session was not accessed but a token is still emitted.
Proposal
Whenever the middleware emits a token (_emit_token) or a clearing cookie:
- set
Cache-Control: private, no-store (overriding a public/max-age value; a token must never be shared), and
- add
Vary for the transport in use (the header name, or Cookie), regardless of session.accessed.
Document the change in SESSION.md. It only affects responses that carry a token, so cacheable responses without one keep their headers.
Problem
When
FastAPICacheXSessionMiddlewaresends a token (a new session, a sliding renewal, or a regenerated ID) it adds nothing that stops a shared cache from storing it.Varyis only added when the handler touchedrequest.session(middleware.py,if session.accessed), and noCache-Controlis set.On a
@cache(ttl=60, public=True)route, a request that happens to trigger sliding renewal gets:A CDN or reverse proxy that stores responses with
Set-Cookiewill hand that cookie, which is a valid session token, to the next visitors. With header transport the token is inX-Session-Token, which proxies do not treat specially at all. With the defaultsliding_threshold=0.5this happens on any request in the second half of a session's TTL.#168 fixed which header name goes in
Vary; it did not cover responses where the session was not accessed but a token is still emitted.Proposal
Whenever the middleware emits a token (
_emit_token) or a clearing cookie:Cache-Control: private, no-store(overriding apublic/max-agevalue; a token must never be shared), andVaryfor the transport in use (the header name, orCookie), regardless ofsession.accessed.Document the change in SESSION.md. It only affects responses that carry a token, so cacheable responses without one keep their headers.