Credentials example in handleFetch hook documentation is incorrect if a cookie was set by SvelteKit
Nobody has claimed this yet.
- #16097 by @starkmarkus — closed without merging
- Dominant language
- JavaScript
- Stars
- 20.8k
- Forks
- 2.3k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 156
Description
Describe the bug
The documentation for handleFetch provides the following example for forwarding cookies to an API on a different domain than SvelteKit is hosted at:
/** @type {import('@sveltejs/kit').[HandleFetch](https://kit.svelte.dev/docs/types#sveltejs-kit-handlefetch)} */
export async function handleFetch({ request, fetch }) {
if (request.url.startsWith('https://api.yourapp.com/')) {
// clone the original request, but change the URL
request = new Request(
request.url.replace('https://api.yourapp.com/', 'http://localhost:9999/'),
request
);
}
return fetch(request);
}
Based on that, I created the following hook to additionally forward cookies from the API server to the client (since it appears that cookies are not forwarded on their own):
import envariant from '@knpwrs/envariant';
import type { HandleFetch } from '@sveltejs/kit';
const GRAPHQL_URL = envariant('GRAPHQL_URL');
const COOKIE_KEY = 'lcSessionId';
export const handleFetch: HandleFetch = async ({ event, request, fetch }) => {
const cookie = event.request.headers.get('cookie');
if (request.url.startsWith(GRAPHQL_URL) && cookie) {
request.headers.set('cookie', cookie);
}
const res = await fetch(request);
const cookieValue = res.headers
.get('set-cookie')
?.replace(`${COOKIE_KEY}=`, '');
if (cookieValue) {
event.cookies.set(COOKIE_KEY, cookieValue, {
sameSite: 'lax',
httpOnly: true,
path: '/',
});
}
return res;
};
The issue is that it appears that SvelteKit is URL-encoding the cookie value with event.cookies.set, but then not URL-decoding the cookie value when reading event.request.headers.get('cookie'). This makes sense as they're different APIs, but it leads to unintuitive bugs where a cookie set by SvelteKit is ultimately not sent to backend APIs in the same form it was set.
Reproduction
- Set a cookie with
- Attempt to forward that cookie using provided example in the documentation
Logs
No response
System Info
System:
OS: macOS 12.1
CPU: (10) arm64 Apple M1 Pro
Memory: 82.08 MB / 32.00 GB
Shell: 5.8 - /opt/homebrew/bin/zsh
Binaries:
Node: 18.10.0 - /nix/store/m3za3mblwg9az7vpkkvlfm04z66mcr6y-nodejs-18.10.0/bin/node
Yarn: 1.22.19 - /opt/homebrew/bin/yarn
npm: 8.19.2 - /nix/store/m3za3mblwg9az7vpkkvlfm04z66mcr6y-nodejs-18.10.0/bin/npm
Watchman: 2022.10.03.00 - /opt/homebrew/bin/watchman
Browsers:
Brave Browser: 106.1.44.101
Chrome: 107.0.5304.110
Chrome Canary: 99.0.4828.0
Firefox: 106.0.5
Safari: 15.2
npmPackages:
@sveltejs/adapter-auto: ^1.0.0-next.88 => 1.0.0-next.88
@sveltejs/kit: ^1.0.0-next.548 => 1.0.0-next.548
svelte: ^3.53.1 => 3.53.1
vite: ^3.1.0 => 3.2.4
Severity
annoyance
Additional Information
IIRC it isn't possible to set the set-cookie header in SvelteKit. Maybe it should be possible to set this header in hooks but not in page/layout handlers? That way backend cookies can be forwarded directly.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the handleFetch server-hooks documentation and the cookie APIs shown in the report. Reproduce the interaction between event.cookies.set, request cookie headers, and set-cookie forwarding, then determine the documented behavior or API change needed so cookies are forwarded consistently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- api, documentation
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100