fix(auth): fix cross-origin logout 401 and CORS Authorization header - #31
Merged
Conversation
Logout was the only /api/auth/* route gated by AuthenticatedUser(), so it required a valid, non-expired Bearer access token. In practice the access token is often expired or already cleared by the time a user logs out, which produced a 401 (observed cross-origin behind the Tencent Cloud proxy). The Logout handler only needs the refresh_token from the request body to revoke the session; it never uses the authenticated user identity. Switch the route to ClientApp() (X-Client-Id) like /refresh, making logout idempotent and independent of access-token state. Update the integration test accordingly.
Access-Control-Allow-Headers was set to the wildcard "*". Per the Fetch spec, "*" does NOT cover the Authorization header, so cross-origin requests carrying a Bearer (or Basic, for /oauth) token fail the preflight and never reach the server. Replace the wildcard with an explicit allow-list that names Authorization, Content-Type, and X-Client-Id, and make the method allow-list explicit too. This keeps cross-origin Bearer endpoints (/api/users, /api/teams, /oauth) working and serves as the correct pattern for other services.
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.
Problem
After deploying the auth backend to Tencent Cloud,
POST /api/auth/logoutreturned 401 Unauthorized. Two distinct issues were found, both around cross-origin / token-state handling.Changes
1. Logout no longer requires a Bearer access token
/api/auth/logoutwas the only/api/auth/*route gated byAuthenticatedUser(), so it demanded a valid, non-expired Bearer access token. But:Logouthandler only readsrefresh_tokenfrom the body to revoke the session — it never uses the authenticated user identity.Fix: route logout through
ClientApp()(X-Client-Id), exactly like/refresh. Logout is now idempotent and independent of access-token state. Integration test updated.2. CORS
Access-Control-Allow-HeaderslistsAuthorizationexplicitlyThe header was set to the wildcard
*. Per the Fetch spec,*does not cover theAuthorizationheader, so any cross-origin request carrying a Bearer (or Basic, for/oauth) token fails the preflight and never reaches the server. Replaced with an explicit allow-list (Authorization, Content-Type, X-Client-Id); methods list made explicit too.This keeps cross-origin Bearer endpoints (
/api/users,/api/teams,/oauth) working and is the correct pattern to mirror when other services (e.g. stride-api) become cross-origin.Testing
gofmtclean on all touched files.TestRegisterLoginRefreshLogoutto sendX-Client-Idfor logout.go build/go testrequires the localreplacedependency (../../../../x) + MySQL, not present in this sandbox; changes add no new imports.