feat: TRAC-268 add graphql proxy for client-side storefront API access#2825
feat: TRAC-268 add graphql proxy for client-side storefront API access#2825chanceaclark wants to merge 1 commit intocanaryfrom
Conversation
🦋 Changeset detectedLatest commit: be3f027 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
c6acb4f to
2b416ac
Compare
9e1889f to
e1ce5a8
Compare
e1ce5a8 to
54d7c74
Compare
54d7c74 to
26e8309
Compare
26e8309 to
d4892a8
Compare
d4892a8 to
ed14c99
Compare
ed14c99 to
de0d201
Compare
|
Marking as |
.changeset/foo-bar-baz.md
Outdated
| customerAccessToken, | ||
| fetchOptions: { | ||
| headers: { | ||
| // DO NOT REMOVE: We pass the request cookies to emulate that this is coming from the browser to the GraphQL API |
There was a problem hiding this comment.
Do we actually need this? Since we’ll be using scoped API tokens without the customer scope for the proxy endpoint, it won’t be able to access sensitive fields such as the customer access token.
The issue with forwarding all browser cookies to the underlying BC SF API is that those cookies are intended for Catalyst, not the BC SF API. They may contain sensitive data (e.g.: third-party analytics cookies), cookie names that BC might unintentionally read if they overlap (e.g.: CSRF tokens), or cause BC to assume a storefront session exists and start treating proxied requests as stateful.
There was a problem hiding this comment.
Do we actually need this? Since we’ll be using scoped API tokens without the customer scope for the proxy endpoint, it won’t be able to access sensitive fields such as the customer access token.
We are thinking about releasing it in the next minor version whether or not the scoped API tokens are ready or not.
The issue with forwarding all browser cookies to the underlying BC SF API is that those cookies are intended for Catalyst, not the BC SF API. They may contain sensitive data (e.g.: third-party analytics cookies), cookie names that BC might unintentionally read if they overlap (e.g.: CSRF tokens), or cause BC to assume a storefront session exists and start treating proxied requests as stateful.
We don't necessarily need to forward all the cookies then, we can pass a dummy value instead. I looked at the storefront service code, and essentially passing this header makes the request behave like it's a request coming directly from the client which applies the same rules as we want from a functionality standpoint as the scoped API token approach.
Also, we don't pass back the response Set-Cookie value back to the client so we won't be passing back stateful information back. I get the point you are trying to make here, but I don't think it's a cause for concern as we are not passing the stateful session cookies back.
There was a problem hiding this comment.
We don't necessarily need to forward all the cookies then, we can pass a dummy value instead.
Thanks for the explanation. Sending a specific cookie set by Catalyst could definitely alleviate some of my concerns. That said, I’m not 100% sure about the potential unintended side effects of this change. It’s worth checking the following to make sure it’s safe to proceed or if it's better to wait for scoped tokens.
- We should verify whether sending a cookie would make the request stateful, meaning starting a new BC storefront session. If so, it could have several implications, e.g.: cart access would require the corresponding session token to be sent back, spam protection might be enforced etc...
- This change could also impact analytics data and potentially skew metrics, since shopper activity is tracked for requests coming from browsers.
- Stateful requests may have to different rate limits than stateless requests. Also, I'm not sure whether including a cookie header could interfere with the trusted proxy setup.
de0d201 to
8583d69
Compare
Bundle Size ReportComparing against baseline from No bundle size changes detected. |
Unlighthouse Performance Comparison — VercelComparing PR preview deployment Unlighthouse scores vs production Unlighthouse scores. Summary ScoreAggregate score across all categories as reported by Unlighthouse.
Category Scores
Core Web Vitals
|
8583d69 to
be3f027
Compare
What/Why?
Add a GraphQL proxy endpoint to the Catalyst proxy layer that allows client-side JavaScript (e.g., checkout-sdk-js) to make GraphQL Storefront API requests without exposing storefront tokens to the browser.
This is a foundational piece that enables:
How it works
POST /graphqlrequests with a validx-catalyst-graphql-proxy-requesterheader are intercepted. All others pass through.ALLOWED_REQUESTERS(currently:checkout-sdk-js).BIGCOMMERCE_STOREFRONT_UNAUTHENTICATED_TOKEN, a dedicated scoped-down token separate from the primaryBIGCOMMERCE_STOREFRONT_TOKEN.auth()wrapper extracts the customer access token from the session and passes it viaX-Bc-Customer-Access-Tokenfor customer-specific queries (e.g., cart, wishlists).Testing
Valid request to the proxy:
Request without valid header:
Request with invalid query (since it's a browser request):
Request with valid query:
Migration
See changeset for full migration steps. Key changes:
BIGCOMMERCE_STOREFRONT_UNAUTHENTICATED_TOKENenv varcore/proxies/with-graphql-proxy.tswithGraphqlProxyincore/proxy.ts(afterwithChannelId, beforewithRoutes)