fix(examples): keep the new-visitor login token out of shared caches - #344
Merged
Merged
Conversation
In examples/session_login.py a visitor with no session logs in through a cookie the handler sets itself. The middleware adds Cache-Control: private, no-store only to tokens it sends, so that response was cacheable. It also left out the configured cookie domain (the cookie cleared at logout did not match) and gave header clients no token. The branch now sends private, no-store, sets the cookie with every cookie_* attribute and returns the token in the header_name response header. The session guide (EN and zh-TW) says the same, and a test checks both login paths against the middleware's own cookie. Closes #322
…cookie A copy in the X-Session-Token response header is readable by page scripts, which defeats HttpOnly. API clients get a token from an endpoint that returns it in the body, as examples/session_jwt.py does; the #293 login() helper will answer on the request's own transport.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
In
examples/session_login.py, a visitor with no session logs in through a cookie the handler sets itself.FastAPICacheXSessionMiddlewareaddsCache-Control: private, no-storeonly to tokens it sends, so that login response was cacheable: a shared cache or CDN could store it and hand the session to the next visitor. The same branch left outdomain=config.cookie_domain(so the cookie expired at logout did not match it).The new-visitor branch now:
Cache-Control: private, no-store;cookie_*attribute of the config (max_age,path,domain,secure,httponly,samesite), the same ones the middleware uses;examples/session_jwt.pydoes. Answering on the request's own transport is part of Session: a supported login() that attaches the user through the middleware #293.The returning-visitor branch (
rotate_session_id+update_session) is unchanged: the middleware sends that token itself, withprivate, no-store.Why not let the middleware issue the token
That was the first choice, but the current API does not allow it. With no session loaded, the middleware creates a session only after the handler returns (anonymous, from a write to
request.session), so the handler cannot attach the user to it. A session the handler creates withcreate_session(user=...)is invisible to the middleware. A supportedlogin()that goes through the middleware is #293; until then the example sets the headers explicitly.Docs
docs/SESSION.md"Regenerate the Session ID After Login" (and the zh-TW mirror) now says what the new-visitor branch must do itself: allcookie_*attributes includingdomain, andCache-Control: private, no-store, and that the token must not be copied into a header or the body of a browser login. The Basic Usage / Quick Start login is left to #321.Tests
tests/test_examples.py::test_session_login_response_is_private, for a new and a returning visitor, withcookie_domainconfigured:Cache-Control: private, no-store;Set-Cookiehas exactly the attributes of a cookie the middleware sets itself (path, max-age, httponly, samesite, domain);X-Session-Token;private, no-storeand an expiring cookie with the same domain and path, and/methen answers 401.Against the unmodified example the new-visitor case fails (no
Cache-Control, and noDomainon the cookie); the returning-visitor case passes, as expected.Changelog:
changelog.d/322.security.md.Closes #322