Fix admin extension CORS preflight in validateAuthenticatedSession#3237
Open
ryandiginomad wants to merge 1 commit into
Open
Fix admin extension CORS preflight in validateAuthenticatedSession#3237ryandiginomad wants to merge 1 commit into
validateAuthenticatedSession#3237ryandiginomad wants to merge 1 commit into
Conversation
…ticatedSession Admin UI extension fetch calls send a CORS preflight (OPTIONS) request without an Authorization header. The middleware would try to authenticate it, redirect/403, and the browser would then block the real request on CORS. Short-circuit OPTIONS requests with a 204 and the CORS headers for https://extensions.shopifycdn.com instead. Fixes Shopify#1420
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
Admin UI extension
fetchcalls to an app's backend (Express template) fail because the CORS preflightOPTIONSrequest is run throughvalidateAuthenticatedSession. The preflight carries noAuthorizationheader, so the middleware redirects/403s it, and the browser then blocks the real (authenticated) request on CORS.A maintainer confirmed the fix direction in #1420:
How
validateAuthenticatedSessionnow short-circuitsOPTIONSrequests before the auth logic runs: it responds204with the CORS headers forhttps://extensions.shopifycdn.com— the origin that Shopify's admin-extensions security docs require apps to allow. The short-circuit is config-agnostic, so it applies to both embedded and non-embedded apps.Before / after
Before:
OPTIONS /api/...→302redirect to/api/auth(or403) → browser blocks the real request on CORS.After:
OPTIONS /api/...→204withAccess-Control-Allow-Origin: https://extensions.shopifycdn.com(+ Allow-Methods / Allow-Headers) → the real request proceeds and is authenticated exactly as before.Tests
Added 3 tests to
validate-authenticated-session.test.ts: preflight returns204without callinggetCurrentId(no auth attempt); allows theAuthorizationheader; allows the request methods. Fullshopify-app-expresssuite: 88 passing, no regressions.tsc+ lint clean. Changeset added (patch).Open to feedback
https://extensions.shopifycdn.comper the docs. Happy to make it configurable or echo a validatedOriginif you'd prefer.GET, POST, PUT, PATCH, DELETE, OPTIONSandAuthorization, Content-Type. Can narrow/widen to match what extensions actually send.Authorizationheader, not cookies). Let me know if a case needs it.AI disclosure
This change was developed with AI assistance (Claude). The approach, code, and tests were reviewed and verified locally by me.
Fixes #1420