Repository navigation
Conversation
JWTRefreshMiddleware appends its own _token Set-Cookie after the response headers. When the route itself sets _token, the browser applies the middleware cookie last, so it overrides the route: - A login route, e.g. an auth manager callback mounted under /auth, sets a fresh token while the request still carries an expired or invalid one. The middleware appends a deletion and the user is logged out right after logging in. - /api/v2/auth/logout deletes the cookie, but if refresh_user returned a refreshed user for that request the middleware appends a newly minted, unrevoked token and the user stays logged in. Skip the middleware token cookie when the response already sets _token. Stale root-path cookies are still cleared. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Backport failed to create: v3-4-test. View the failure log Run detailsNote: As of Merging PRs targeted for Airflow 3.X In matter of doubt please ask in #release-management Slack channel.
You can attempt to backport this manually by running: cherry_picker 99eff46 v3-4-testThis should apply the commit to the v3-4-test branch and leave the commit in conflict state marking After you have resolved the conflicts, you can continue the backport process by running: cherry_picker --continueIf you don't have cherry-picker installed, see the installation guide. |
Backport successfully created: v3-4-testNote: As of Merging PRs targeted for Airflow 3.X In matter of doubt please ask in #release-management Slack channel.
|
…are (#75217) (#75454) JWTRefreshMiddleware appends its own _token Set-Cookie after the response headers. When the route itself sets _token, the browser applies the middleware cookie last, so it overrides the route: - A login route, e.g. an auth manager callback mounted under /auth, sets a fresh token while the request still carries an expired or invalid one. The middleware appends a deletion and the user is logged out right after logging in. - /api/v2/auth/logout deletes the cookie, but if refresh_user returned a refreshed user for that request the middleware appends a newly minted, unrevoked token and the user stays logged in. Skip the middleware token cookie when the response already sets _token. Stale root-path cookies are still cleared. (cherry picked from commit 99eff46) Co-authored-by: Mathieu Monet <60776491+stegololz@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
JWTRefreshMiddlewareappends its own_tokenSet-Cookieheader after the response headers. When the route has already set_tokenitself, browsers apply the headers in order, so the middleware's cookie overrides the route's cookie:/auth) sets a fresh_token, but the request still carries an expired, revoked or otherwise invalid one.resolve_user_from_tokenfails, the middleware appends_token=""; Max-Age=0after the fresh cookie, and the user is logged out right after logging in./api/v2/auth/logoutrevokes the presented tokens and deletes the cookie. But ifrefresh_userreturned a user for that same request, the middleware mints a new token before the route runs. It then appends that token after the route's deletion. The new token was never revoked, so the user stays logged in.The Keycloak provider already works around the login case in its own middleware (
request.state.jwt_token_issued). That only helps Keycloak's login route, not other auth managers and not the logout case.Fix: in
send_with_cookies, skip the middleware's_tokencookie when the response already sets_token. The cleanup of a stale root-path_token(#64955) is still appended, because it targets a different path.Tests: three new tests in
test_refresh_token.py, which fail without the fix:_token: only the route's cookie is sentRelated: #74722, #70783 and #70707 touch the same middleware; this change is independent of them.
Was generative AI tooling used to co-author this PR?
Generated-by: Claude Code (Opus 5.5) following the guidelines