Open johnboxall opened 1 year ago
A specific case where it is useful to have the "shopper" facing host is when doing CORS – you might want to decide whether to respond with Access-Control-Allow-Origin
headers based on the requested host and to do that, you'd need the origin host.
To implement X-Forwarded-Host
in user space, you can:
X-Forwarded-Host
header. Most CDN provide rules to allow you to do this, for example in CloudFlare, you can use Transform rules to dynamically add the header.request-processor.js
to grab the X-Forwarded-Host
header and add it to the request class. This is required to make the cache key vary this header.ssr.js
to use the header!// request-processor.js
// 1️⃣ Grab the shopper facing host and put it in the request class to vary cache keys by it.
export const processRequest = ({setRequestClass, headers, path, querystring}) => {
const host = headers.getHeader('x-forwarded-host')
setRequestClass(new URLSearchParams({host}))
return { path, querystring }
}
// app/ssr.js
// 2️⃣ Dig out the value. Use it however you want to vary responses!
app.get('/', (req, res) => {
res.json({host: req.get('x-forwarded-host'})
})
When we think about how we want to expose this, it should use Express' trust proxy feature:
https://expressjs.com/en/guide/behind-proxies.html
This would make req.hostname
behave as folks expect.
This is related to #1667.
Not super keen on 1 as that means you have to setup the custom domain twice on eCDN and MRT. More friction to the launch process.
Hi @drewzboto @johnboxall, sorry to bother you but any news on this? As far as we know the eCDN currently does not pass the x-forwarded-host header by default so I'm afraid the suggested solution will not work as intended when the stacked CDN is the eCDN one.
Hey @mgalassi – if you submit a support request, internal teams can help enabled the x-forwarded-host
header on your eCDN zone:
Please note that this is a best effort process and no SLA is provided so if you require eCDN to append this header ask early!
This issue is also related to https://github.com/SalesforceCommerceCloud/pwa-kit/issues/1415, as you may want to use it to vary site based on the incoming request.
Hi @johnboxall, that's what I did some days after writing the comment and I can confirm to everyone that the support team can indeed try to add the header to specific domains. I have asked the team to add it to one of our domains for testing and then they would take approx. 2-3 weeks to add it to all the other domains as well (we are talking about 8-9 four/third level domains that can be easily managed by a single environment).
As always, thank you very much John!
When a CDN like eCDN is stacked on top of PWA Kit / MRT, the app may be unaware of the origin that the shoppers browser has landed on. This can result in:
For the purposes of describing the problem, lets imagine a stacked CDN with the domain
www.example.com
and a MRT environment with the domainexample-production.mobify-storefront.com
in a stacked setup:Within the PWA Kit, the
getAppOrigin
utility function andprocess.env.APP_ORIGIN
environment variable are used to help construct URLs used to make requests both in browser and on MRT:https://github.com/SalesforceCommerceCloud/pwa-kit/blob/51bf787c046d7d8d53cb97d21bb6a79e5bc20c60/packages/pwa-kit-react-sdk/src/utils/url.js#L21-L35 https://github.com/SalesforceCommerceCloud/pwa-kit/blob/51bf787c046d7d8d53cb97d21bb6a79e5bc20c60/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.js#L140
They are set to
process.env.EXTERNAL_DOMAIN_NAME
, which comes from a MRT environment's external domain (eg.example-production.mobify-storefront.com
)In a stacked setup, this is the wrong domain for building client side absolute URLs.
The browser's origin will be
www.example.com
, but requests will end up being routed toexample-production.mobify-storefront.com
, which will result in CORS issues.There are a few potential user-space work arounds today:
1️⃣ Make the MRT env accept requests on the same domain as the CDN
www.example.com
)www.example.com
. At this point, the MRT env will not be directly accessible from the browser as the DNS entry forwww.example.com
will point to the CDN.example-production-cdn.mobify-storefront.com
with HTTPHost: www.example.com
.2️⃣ Static Configuration
www.example.com
domain.getAppOrigin()
to make requests, use the domain from the config files..3️⃣ Dynamic Configuration
x-forwarded-host
HTTP request header.X-Forwarded-Host: www.example.com
in requests to MRT.getAppOrigin()
, use this forwarded value to make requests client side. The request class is available via thewindow.Progressive
global object.4️⃣ Use relative URLs in browser
One other solution that may work is to use relative URLs when requests are being made to proxies in browser.
It would seem useful to have first class support for one of these options.
When we think about "desirable qualities" of a solution ... ideally: