fix(auth): stop stale session cookies signing users out on refresh

@supabase/ssr 0.1.0 never removed the old unchunked session cookie once a
refreshed session grew past one cookie, and always read that stale copy
first. Every load then retried an already-used refresh token, which the
hosted auth server rejects, signing the user out.

Upgrade @supabase/ssr to 0.12 (and supabase-js to match) and move to the
getAll/setAll cookie API, which clears stale chunks when writing.
This commit is contained in:
Josh Creek
2026-09-14 16:19:20 +01:00
parent f382176804
commit b7d2db4959
5 changed files with 97 additions and 129 deletions
+8 -11
View File
@@ -1,23 +1,20 @@
import { PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY } from '$env/static/public';
import { createServerClient } from '@supabase/ssr';
import type { Handle } from '@sveltejs/kit';
import type { CookieSerializeOptions } from 'cookie';
export const handle: Handle = async ({ event, resolve }) => {
event.locals.supabase = createServerClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
cookies: {
get: (key: string) => event.cookies.get(key),
getAll: () => event.cookies.getAll(),
/**
* Note: You have to add the `path` variable to the
* set and remove method due to sveltekit's cookie API
* requiring this to be set, setting the path to an empty string
* will replicate previous/standard behaviour (https://kit.svelte.dev/docs/types#public-types-cookies)
* Note: You have to add the `path` variable to the set method due to sveltekit's cookie
* API requiring this to be set, setting the path to '/' will replicate previous/standard
* behaviour (https://kit.svelte.dev/docs/types#public-types-cookies)
*/
set: (key: string, value: string, options: CookieSerializeOptions) => {
event.cookies.set(key, value, { ...options, path: '/' });
},
remove: (key: string, options: CookieSerializeOptions) => {
event.cookies.delete(key, { ...options, path: '/' });
setAll: (cookiesToSet) => {
cookiesToSet.forEach(({ name, value, options }) => {
event.cookies.set(name, value, { ...options, path: '/' });
});
}
}
});