Skip to content

Treat a login cookie with an expired access token as logged out - #1057

Open
TanmayS0406 wants to merge 1 commit into
dotnet:mainfrom
TanmayS0406:fix-expired-access-token
Open

TanmayS0406 wants to merge 1 commit into
dotnet:mainfrom
TanmayS0406:fix-expired-access-token

Conversation

@TanmayS0406

Copy link
Copy Markdown

Related to #9.

Problem

The WebApp keeps the user signed in with a cookie that is renewed while they are active, but the access token stored inside it expires after 2 hours (AccessTokenLifetime in Identity.API) and is never renewed. Once it has expired:

  • the WebApp still shows the user as logged in, because the cookie is valid;
  • GetBasket succeeds, because it is [AllowAnonymous] and returns an empty basket when there is no user;
  • UpdateBasket and DeleteBasket fail with RpcException: Status(StatusCode="Unauthenticated", Detail="The caller is not authenticated."), so adding to the cart ends in a 500.

That matches what is described in #9 (logged in, GetBasketAsync succeeds, UpdateBasketAsync fails with Unauthenticated, fixed by logging out and in). The reporter there describes a non-expired token, so I can't say this is the only way to reach that state, which is why this is "related to" and not "fixes".

Change

OnValidatePrincipal on the cookie now rejects the principal and signs out when the expires_at token stored in the cookie is in the past. The user is then treated as logged out and asked to log in again.

Verification

Reproduced and fixed by running Identity, Basket, Catalog, Ordering and the WebApp locally and driving the site with Playwright. To avoid waiting 2 hours, I temporarily set the webapp client's AccessTokenLifetime to 10 seconds (not part of this PR), logged in as alice, waited past the token's expiry plus the API's 5 minute clock skew, then added an item to the cart.

Item page shows Add to cart
main "Add to shopping bag" POST /item/1 returns 500, Unauthenticated in the WebApp and Basket API logs
This PR "Log in to purchase" Redirected to the Identity login page, no Unauthenticated in the logs

The existing Playwright suite (browse, cart, checkout) passes with the normal 2 hour lifetime.

Not covered

  • No automated test: the failure needs an access token to expire, and Application.UnitTests has no reference to the WebApp. I can add one if you prefer to expose the handler for testing.
  • A token that the API rejects for another reason while still unexpired (for example after Identity restarts with a new signing key) is not handled by this change.

🤖 Generated with Claude Code

The WebApp renews the login cookie while the user is active, but the
access token stored in it expires after 2 hours and is never renewed.
Once it has, the WebApp still shows the user as logged in while the APIs
treat them as anonymous: reading the basket succeeds (it is anonymous
and returns an empty basket) but any write fails with RpcException
Unauthenticated, so adding to the cart ends in a 500.

Reject the cookie when its access token has expired, so the user is
signed out and asked to log in again.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant