kit: Server-side `fetch` in `load` is not credentialed
Describe the bug
No credentials are passed on in a server-side fetch
.
To Reproduce On a fresh kit project:
<!-- src/routes/index.svelte -->
<script context="module">
export async function load({ fetch }) {
await fetch(`http://localhost:3000/test`, {
credentials: "include",
mode: "cors",
});
return true;
}
</script>
<h1>blah</h1>
// src/routes/test.js
export async function get(request) {
console.log(request);
return {
body: {
data: 1234,
},
};
}
// src/setup/index.js
export async function prepare() {
return {
headers: {
"Set-Cookie": "test=1234",
},
};
}
Load http://localhost:3000 twice.
Expected behavior Cookie header should appear in server console on second load.
Information about your SvelteKit Installation:
System:
OS: Windows 10 10.0.19042
CPU: (16) x64 AMD Ryzen 7 3700X 8-Core Processor
Memory: 12.38 GB / 31.95 GB
Binaries:
Node: 14.16.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.10 - ~\AppData\Roaming\npm\yarn.CMD
npm: 7.6.1 - C:\Program Files\nodejs\npm.CMD
Browsers:
Chrome: 89.0.4389.90
Edge: Spartan (44.19041.423.0), Chromium (89.0.774.54)
Internet Explorer: 11.0.19041.1
npmPackages:
@sveltejs/kit: next => 1.0.0-next.59
svelte: ^3.29.0 => 3.35.0
Severity Blocking for any project that requires credentialed server-side requests.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 5
- Comments: 30 (16 by maintainers)
Links to this issue
Commits related to this issue
- failing test for #672 — committed to sveltejs/kit by Rich-Harris 3 years ago
- Credentialed fetch from `load` (#835) * failing test for #672 * pass credentials to internal fetch where appropriate * changeset — committed to sveltejs/kit by deleted user 3 years ago
This feels like a common use case for SvelteKit. I want to write my frontend in SvelteKit and have a separate api. What would be the optimal way to do this? Using token-based auth? Something else?
Reopening as this is not quite fixed. Internal fetches like
fetch('/test')
work.“External” fetches like
fetch('http://localhost:3000/test')
(yes, same origin) do not have headers passed even if we explicitly include credentials:Probably because we don’t pass it to the external node fetch: https://github.com/sveltejs/kit/blob/108c26cb797a7d09dda5f287cd17ee9f02bc914a/packages/kit/src/runtime/server/page.js#L82-L85
This is a blocker for me as well, as I don’t really understand how to interact with my backend while it’s not implemented within sveltekit and uses cookie-based authentication.
I don’t know how much workaround is it, but for now I’m using this approach:
myproject/src/routes/api/[…route].ts:
This way I’m able to pass cookie back and forth, so this code kind of works:
Doesn’t seem to me as an optimal approach, because in involves some manual parsing and non-obvious assumptions. Hope for some solution from @Rich-Harris as well.
I think this is beyond the scope of the original issue so I’ll file a new one specifically for same-origin “external” fetches.
I’d just like to add that I am also being frustrated by this bug.
A Graphql server on localhost:8080 and site on localhost:3000 and they don’t play nicely. In production I’d like to have the api on a subdomain.
These are pretty normal setups and should not be so difficult to get working.
I can’t understand why this issue is closed.
in order to move forward here a) (optional) node-fetch needs to accept the pull request https://github.com/node-fetch/node-fetch/pull/1116 b) sveltekit needs to actually set the cookie headers etc. if
credentials
is true. likewise to sapperMy problems are for situations where the domain is the same though. A cookie can be shared across subdomains or ports. That is not a browser limitation.
Edit: and yes, I’m also trying to use Apollo so need to use the full URL
i was able to make it work by adding this code here after line 90
You also need to add
import { parse as parseCookie } from 'cookie';
at the beginning
then rebuild sveltekit via
npm run build
and copy the/dist/ssr.js
over to your local npm folderit works now and my server side rendering is actually sending the cookie credentials to the backend. However i am hesitant to open a Pull Request because i feel like i am not understanding 100% of the puzzle and don’t want to make any troubles (e.g. sapper is actually merging the request & response cookies (by looking at the SET-Cookie header from the response) but i don’t know how this can be done in sveltekit)
The original bug has been resolved. There’s not a way to know about what cookies exist on other domains during SSR. Supporting the Express middleware API was discussed internally and decided against. If they want, someone could write a userland interop module between the Express API and the
handle
hook.