Found while writing examples/session_login.py (#291). Under FastAPICacheXSessionMiddleware there is no supported way to log a user in so that require_user_session / AuthenticatedSession (new in 0.3.8) accept the request afterwards.
Problems
- A visitor without a session. The middleware only sends tokens for sessions it loaded, or created from a write to
request.session. A session made with SessionManager.create_session(user=...) in the handler is not sent. The example builds the cookie by hand from the SessionConfig fields, which duplicates the middleware's cookie logic. With header or Authorization: Bearer transport there is no equivalent at all.
- Attaching the user to a loaded session. After
rotate_session_id(request), setting session.user = user is not saved unless request.session is also modified. The example calls await manager.update_session(session) explicitly.
- The documented login pattern does not produce a user. The
rotate_session_id docstring and SESSION.md log in with request.session["user_id"] = "123". That never sets session.user, so require_user_session / AuthenticatedSession answer 401 for that "logged-in" user.
Proposal (additive, 0.3.9)
- A request-level helper, e.g.
await login(request, user). It rotates the loaded session's ID (or starts a new session if none was loaded), attaches the SessionUser and marks the session for saving. The middleware then sends the new token through the request's transport: cookie, header or Bearer.
- Document it as the way to log in whenever
require_user_session / AuthenticatedSession is used. Update the rotate_session_id docstring, SESSION.md (EN and zh-TW) and examples/session_login.py, which drops its manual cookie and update_session() call.
- Say plainly that
request.session["user_id"] is application data: the library does not treat it as a login.
#256 (0.4.0) builds on this: login() becomes the only way to attach a user, and setting Session.user directly stops working. Choosing the name and shape here in 0.3.9 keeps that later change small.
Tests
- New visitor →
login() → AuthenticatedSession route answers 200, for each transport.
- Existing anonymous session →
login(): the old token no longer resolves, the data is kept, and the user is attached.
login() inside a request that also writes request.session saves both.
Found while writing
examples/session_login.py(#291). UnderFastAPICacheXSessionMiddlewarethere is no supported way to log a user in so thatrequire_user_session/AuthenticatedSession(new in 0.3.8) accept the request afterwards.Problems
request.session. A session made withSessionManager.create_session(user=...)in the handler is not sent. The example builds the cookie by hand from theSessionConfigfields, which duplicates the middleware's cookie logic. With header orAuthorization: Bearertransport there is no equivalent at all.rotate_session_id(request), settingsession.user = useris not saved unlessrequest.sessionis also modified. The example callsawait manager.update_session(session)explicitly.rotate_session_iddocstring andSESSION.mdlog in withrequest.session["user_id"] = "123". That never setssession.user, sorequire_user_session/AuthenticatedSessionanswer401for that "logged-in" user.Proposal (additive, 0.3.9)
await login(request, user). It rotates the loaded session's ID (or starts a new session if none was loaded), attaches theSessionUserand marks the session for saving. The middleware then sends the new token through the request's transport: cookie, header or Bearer.require_user_session/AuthenticatedSessionis used. Update therotate_session_iddocstring,SESSION.md(EN and zh-TW) andexamples/session_login.py, which drops its manual cookie andupdate_session()call.request.session["user_id"]is application data: the library does not treat it as a login.#256 (0.4.0) builds on this:
login()becomes the only way to attach a user, and settingSession.userdirectly stops working. Choosing the name and shape here in 0.3.9 keeps that later change small.Tests
login()→AuthenticatedSessionroute answers200, for each transport.login(): the old token no longer resolves, the data is kept, and the user is attached.login()inside a request that also writesrequest.sessionsaves both.