feat(session): add login() that attaches the user through the middleware - #351
Merged
Merged
Conversation
login(request, user) rotates the loaded session's ID (or starts a new session), attaches the SessionUser, and lets FastAPICacheXSessionMiddleware send the token through the request's transport, so AuthenticatedSession accepts the next request. The login example drops its hand-built cookie and update_session() call, and the session guide documents login() as the way to log in.
When the loaded session belongs to a different user_id, login() now deletes it and empties request.session instead of rotating it, so none of the previous user's data reaches the new one. Anonymous sessions and re-logins of the same user_id still keep their data and rotate.
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.
What
Adds
login(request, user)tofastapi_cachex.session: the supported way to log a user in underFastAPICacheXSessionMiddlewareso thatrequire_user_session/AuthenticatedSessionaccept the next request.user_id(a re-login): the same, and the newSessionUserreplaces the stored one, so changed roles or metadata take effect.request.sessionis emptied, so neither its data nor writes made earlier in the request reach the new user (as Django'slogin()flushes). A new session is started, its old token no longer resolves, and writes afterlogin()are saved as usual.Authorization: Bearertoken, otherwise an HttpOnlySet-Cookie. The response getsCache-Control: private, no-store, as every token-carrying response already does. Keys written torequest.sessionbefore or after the call are saved into the logged-in session (earlier writes are dropped when the session was another user's).login()returns the session, andget_sessionreturns it for the rest of the request.Edge cases (documented in the docstring and the guide)
FastAPICacheXSessionMiddleware(no middleware, or the deprecated header-onlySessionMiddleware, which cannot send a token for a session it did not load):RuntimeErrorwith a message that names the middleware.clear()afterlogin()in the same request is a logout: the new session is deleted and no token is sent (a cookie client gets its cookie expired).clear()beforelogin(): the loaded session is logged out (deleted), andlogin()starts a new session instead of rotating the cleared one.manager.issue_token(session)for the returned session.login()twice rotates again and keeps the last user.How
_RequestSessionnow records the backend session it belongs to and the middleware that created it.login()updates that record, and the middleware reads it when the response starts, instead of the session it loaded. The existing "session ID changed, so send a token for the new ID" path then handles both transports. TheFastAPICacheXSessionMiddlewarepublic API is unchanged.Docs and example
rotate_session_iddocstring andSESSION.md(EN + zh-TW) now documentlogin()as the way to log in. They state plainly thatrequest.session["user_id"]is application data, not a login.rotate_session_idstays documented for rotating without a login.examples/session_login.pyuseslogin(). It no longer builds the cookie by hand, callsupdate_session()or setsCache-Controlitself.test_session_login_response_is_privatestill passes, since the middleware sets the header.changelog.d/293.added.md.Tests
tests/session/test_login.py:AuthenticatedSessionroute, for cookie, header and Bearer;user_idkeeps the data and updates the user; an anonymous login keeps writes made beforelogin();login(),login()thenclear()(cookie and header),clear()thenlogin(), login twice, IP / User-Agent binding;RuntimeErroroutside the middleware and under the deprecatedSessionMiddleware.The key tests were mutation-checked: each targeted mutation of the implementation made at least one of them fail.
Closes #293