-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Describe the bug
I have two apps served behind a reverse proxy; requests to /api/* get forwarded to my API server, and all the others are forwarded to my SvelteKit app.
In my SvelteKit app's load functions, I use fetch('/api/some-api-endpoint') to send requests to the API (which is, again, separate from the SvelteKit app). I also have a handleFetch hook that looks at these requests, and and changes their URL to fetch('http://localhost:5000/some-api-endpoint') (where localhost:5000 is the server app), in order to take a shortcut (very similar to the example in the docs).
The problem is I have to manually forward the Cookie header and so on, because the modified URL is no longer considered the same origin:
export async function handleFetch({ request, event, fetch }) {
const thisOrigin = new URL(event.request.url).origin;
if (request.url.startsWith(thisOrigin + '/api')) {
request = new Request(request.url.replace(thisOrigin, PRIVATE_API_ORIGIN), request);
// Manually forward headers...
}
return fetch(request);
}SvelteKit will also automatically send an Origin header along with the request, which is not actually needed in this case, because (thankfully) SvelteKit only "simulates" CORS based on the "original" URL, and not the URL coming out of handleFetch, and rightly so, because handleFetch only runs on the server:
kit/packages/kit/src/runtime/server/page/load_data.js
Lines 237 to 240 in dbbd4c7
| throw new Error( | |
| `CORS error: ${ | |
| acao ? 'Incorrect' : 'No' | |
| } 'Access-Control-Allow-Origin' header is present on the requested resource` |
What I'm suggesting is that all the logic here:
kit/packages/kit/src/runtime/server/fetch.js
Lines 34 to 70 in dbbd4c7
| if (!request.headers.has('origin')) { | |
| request.headers.set('origin', event.url.origin); | |
| } | |
| if (info !== original_request) { | |
| mode = (info instanceof Request ? info.mode : init?.mode) ?? 'cors'; | |
| credentials = | |
| (info instanceof Request ? info.credentials : init?.credentials) ?? 'same-origin'; | |
| } | |
| // Remove Origin, according to https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin#description | |
| if ( | |
| (request.method === 'GET' || request.method === 'HEAD') && | |
| ((mode === 'no-cors' && url.origin !== event.url.origin) || | |
| url.origin === event.url.origin) | |
| ) { | |
| request.headers.delete('origin'); | |
| } | |
| if (url.origin !== event.url.origin) { | |
| // Allow cookie passthrough for "credentials: same-origin" and "credentials: include" | |
| // if SvelteKit is serving my.domain.com: | |
| // - domain.com WILL NOT receive cookies | |
| // - my.domain.com WILL receive cookies | |
| // - api.domain.dom WILL NOT receive cookies | |
| // - sub.my.domain.com WILL receive cookies | |
| // ports do not affect the resolution | |
| // leading dot prevents mydomain.com matching domain.com | |
| // Do not forward other cookies for "credentials: include" because we don't know | |
| // which cookie belongs to which domain (browser does not pass this info) | |
| if (`.${url.hostname}`.endsWith(`.${event.url.hostname}`) && credentials !== 'omit') { | |
| const cookie = get_cookie_header(url, request.headers.get('cookie')); | |
| if (cookie) request.headers.set('cookie', cookie); | |
| } | |
| return fetch(request); | |
| } |
Should ALSO be based on the "original" URL (and not the URL modified by handleFetch), in order to simulate browser behavior more accurately. The current behavior is inconsistent. Tell me if I'm wrong.
Reproduction
N/A
Logs
No response
System Info
System:
OS: Linux 5.15 Ubuntu 22.04.2 LTS 22.04.2 LTS (Jammy Jellyfish)
CPU: (4) x64 Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz
Memory: 8.07 GB / 11.63 GB
Container: Yes
Shell: 3.6.1 - /home/linuxbrew/.linuxbrew/bin/fish
Binaries:
Node: 20.6.0 - /home/linuxbrew/.linuxbrew/bin/node
npm: 9.8.1 - /home/linuxbrew/.linuxbrew/bin/npm
pnpm: 8.7.1 - /home/linuxbrew/.linuxbrew/bin/pnpm
bun: 1.0.11 - ~/.bun/bin/bun
npmPackages:
@sveltejs/adapter-node: ^1.3.1 => 1.3.1
@sveltejs/kit: ^1.27.6 => 1.27.6
svelte: ^4.2.5 => 4.2.5
vite: ^4.5.0 => 4.5.0Severity
serious, but I can work around it
Additional Information
No response