Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cookie is too large #643

Open
mbalslow opened this issue Sep 25, 2023 · 35 comments
Open

Cookie is too large #643

mbalslow opened this issue Sep 25, 2023 · 35 comments
Assignees
Labels
bug Something isn't working

Comments

@mbalslow
Copy link

mbalslow commented Sep 25, 2023

Bug report

Describe the bug

I have a SvelteKit app that uses the latest await supabase.auth.exchangeCodeForSession(code); auth logic with Azure as the provider and everything works fine. However, if I attempt to expand my "scopes" with offline_access to get the provider_refresh_token, I get the following error:

Error: Cookie "sb-xxxxxxxxxxxxx-auth-token" is too large, and will be discarded by the browser
    at set_internal (C:/Users/mbalslow/GitHub/basico-mit-website/node_modules/@sveltejs/kit/src/runtime/server/cookie.js:195:11)
    at Object.set (C:/Users/mbalslow/GitHub/basico-mit-website/node_modules/@sveltejs/kit/src/runtime/server/cookie.js:114:4)
    at SvelteKitServerAuthStorageAdapter.setCookie (file:///C:/Users/mbalslow/GitHub/basico-mit-website/node_modules/@supabase/auth-helpers-sveltekit/dist/index.js:80:24)
    at SvelteKitServerAuthStorageAdapter.setItem (C:\Users\mbalslow\GitHub\basico-mit-website\node_modules\@supabase\auth-helpers-shared\dist\index.js:276:10)
    at setItemAsync (C:\Users\mbalslow\GitHub\basico-mit-website\node_modules\@supabase\gotrue-js\dist\main\lib\helpers.js:129:19)
    at SupabaseAuthClient._persistSession (C:\Users\mbalslow\GitHub\basico-mit-website\node_modules\@supabase\gotrue-js\dist\main\GoTrueClient.js:1328:43)
    at SupabaseAuthClient._saveSession (C:\Users\mbalslow\GitHub\basico-mit-website\node_modules\@supabase\gotrue-js\dist\main\GoTrueClient.js:1323:24)
    at SupabaseAuthClient._exchangeCodeForSession (C:\Users\mbalslow\GitHub\basico-mit-website\node_modules\@supabase\gotrue-js\dist\main\GoTrueClient.js:353:24)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async C:\Users\mbalslow\GitHub\basico-mit-website\node_modules\@supabase\gotrue-js\dist\main\GoTrueClient.js:643:28

As soon as I remove offline_access, it works. It seems that too much data in put into the same cookie.

Expected behavior

Maybe an option to have the provider details in a separate cookie or somehow be able to control how the session is stored in one or more cookies. The current implementation makes it impossible to get a hold of the provider_refresh_token, which is critical for our implementation.

@mbalslow mbalslow added the bug Something isn't working label Sep 25, 2023
@silentworks
Copy link
Contributor

This is a known issue with cookies that they have a size limit. You can create your own cookie storage driver for the auth-helpers and handle cookie chunking in it. We had something we were working on to handle the chunking but we had issues in Safari.

@silentworks silentworks self-assigned this Sep 30, 2023
@mbalslow
Copy link
Author

Can you point me in some direction on how to do this @silentworks?

@silentworks
Copy link
Contributor

@mbalslow I have a working branch at the moment that will get merged in within the next few days to resolve this issue. Here is the PR #653

@tobiassern
Copy link

@silentworks I see that this has now been merged, thank you for fixing it. But how do I use it, my current code is the same as is the same as in the tutorial -> https://supabase.com/docs/guides/auth/server-side/creating-a-client?framework=sveltekit

What do i need to change, update in order to get this to work?

@silentworks
Copy link
Contributor

@tobiassern the update you saw here was related to @supabase/auth-helpers and not @supabase/ssr. However we have now shipped this feature in the @supabase/ssr package too. But for SvelteKit there is a caveat in the createBrowser where you need to setup the cookies.get to handle chunking. I will add this to the guides soon.

@tobiassern
Copy link

@silentworks thank you for the update, looking forward to the updated guides.

@silentworks
Copy link
Contributor

@tobiassern updated guides are now published.

@mattiasbonte
Copy link

mattiasbonte commented Nov 4, 2023

Hello guys, I've implemented the chunking as described in the new documentation and updated my package to 0.0.8. But it seems now the logout action doesn't actually log out the user anymore. Does someone else encounter the same issue or is this something on my end?

I believe this issue is related/possibly the same. Since I now have 2 cookies with undefined living in my cookie storage at all times. Even when logged out.

@silentworks
Copy link
Contributor

@mattiasbonte there was a bug in 0.0.8, we've since reverted the change that caused the bug and released 0.0.9. Please test out 0.0.9 and let us know if the issue has been resolved.

@mattiasbonte
Copy link

Hey @silentworks, I've downloaded the update and did a full test and now I see the undefined cookies are indeed gone and renamed to sb-oqwjnxpmowajlgwaoqcs-auth-token.0 and sb-oqwjnxpmowajlgwaoqcs-auth-token.1.

But the logout functionality is still broken. The thing is, when the supabase.auth.signOut() function is executed the cookie storage is still populated with the 2 cookies mentioned above. I assume this is the reason the logout fails?

@silentworks
Copy link
Contributor

@mattiasbonte you will need to create a reproducible example of this as I've tested this on my side and cannot replicate this issue.

@mattiasbonte
Copy link

You can have this code in the src/routes/layout.ts file to reproduce.

	/**
	 * Supabase Client Side (Browser) Client.
	 * @info The server side client lives in `hooks.server.ts`
	 */
	const supabase = createBrowserClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
		global: {
			fetch,
		},
		cookies: {
			get(key) {
				if (!isBrowser()) {
					return JSON.stringify(data.session);
				}
				const cookie = combineChunks(key, (name) => {
					const cookies = parse(document.cookie);
					return cookies[name];
				});
				return cookie;
			},
		},
	});
	
	// should directly sign the user out after instantiation?
	await supabase.auth.signOut();
       // but nothing happens.

@silentworks So when I use the supabase server client to execute the auth.signOut action, everything works as expected.
It's when I use the browser client that it fails to work. I've tried to call my browser client in different parts of the app but all with the same result.

Does the signout action works on both your browserClient and serverClient? If yes, I will have to dig deeper.

@silentworks
Copy link
Contributor

@mattiasbonte That is not how you would write a signout with the library. Please provide a reproducible Github repo, the snippets you are providing doesn't make much sense to someone else who doesn't have context of your project. Also you should probably create a new issue as this is no longer related to this original issue here.

@dvvolynkin
Copy link

@silentworks

export const createSupabaseRouteHandlerClient = (anon: boolean = true): SupabaseClient<Database> => {
  const cookieStore = cookies()

  return sbSSR.createServerClient<Database>(
    env.NEXT_PUBLIC_SUPABASE_URL!,
    anon ? env.NEXT_PUBLIC_SUPABASE_ANON_KEY! : env.SUPABASE_SERVICE_ROLE_KEY!,
    {
      cookieOptions: getCookieOptions(),
      cookies: {
        get(name: string) {
          return cookieStore.get(name)?.value
        },
        set(name: string, value: string, options: sbSSR.CookieOptions) {
          console.log("cookie length", value.length)
          cookieStore.set({ name, value, ...options })
        },
        remove(name: string, options: sbSSR.CookieOptions) {
          cookieStore.set({ name, value: '', ...options })
        },
      },
    }
  )
}

cookie length in chunk is 3143

But after encoding in Set-Cookie header value length is 4262

@silentworks
Copy link
Contributor

@dvvolynkin it would be useful to see the content your getCookieOptions() function returns.

@dvvolynkin
Copy link

export const getCookieOptions = (): sbSSR.CookieOptions => {
  const hostname = new URL(env.NEXT_PUBLIC_APP_URL).hostname;
  const isHostSecure = env.NEXT_PUBLIC_APP_URL.startsWith('https://');
  const twelveMonths = 60 * 60 * 24 * 30 * 12;
  return {
    domain: hostname,
    path: '/',
    secure: isHostSecure,
    sameSite: 'none',
    maxAge: twelveMonths
  };
};

@sharkstate
Copy link

@tobiassern the update you saw here was related to @supabase/auth-helpers and not @supabase/ssr. However we have now shipped this feature in the @supabase/ssr package too. But for SvelteKit there is a caveat in the createBrowser where you need to setup the cookies.get to handle chunking. I will add this to the guides soon.

Ive made the changes posted in the guide here:

https://supabase.com/docs/guides/auth/server-side/creating-a-client?framework=sveltekit&environment=layout

eg added:

import { combineChunks, createBrowserClient, isBrowser, parse } from '@supabase/ssr'

however, get:

The requested module '...@supabase_ssr.js?v=3acaaab5' does not provide an export named 'combineChunks'

@sharkstate
Copy link

@tobiassern the update you saw here was related to @supabase/auth-helpers and not @supabase/ssr. However we have now shipped this feature in the @supabase/ssr package too. But for SvelteKit there is a caveat in the createBrowser where you need to setup the cookies.get to handle chunking. I will add this to the guides soon.

Ive made the changes posted in the guide here:

https://supabase.com/docs/guides/auth/server-side/creating-a-client?framework=sveltekit&environment=layout

eg added:

import { combineChunks, createBrowserClient, isBrowser, parse } from '@supabase/ssr'

however, get:

The requested module '...@supabase_ssr.js?v=3acaaab5' does not provide an export named 'combineChunks'

Sorry. Got it, 0.0.9

@DiegusAurelius
Copy link

@tobiassern updated guides are now published.

Im having the same exact issue. IM using the SSR package 0.0.10, and Sveltekit 2.0.0. While authenticating with Facebook and Magic Link I get a 500 Internal error and "Cookie "sb-******-auth-token.1" is too large, and will be discarded by the browser. I tried the combineChunk method, but didn't work.

@badgifter
Copy link

badgifter commented Jan 4, 2024

Got same issue as well. For us, we were setting avatar_local="server.com/v1/storage/etc/etc/uuid/img_name_is_really_long_for_some_random_reason_prob_ai_gen_image.webp?width=200

I noticed when a person uploads a large name image for their avatar, once we set the avatar_url in their user_info, login no longer worked. I think the chunks being made didn't account for large key:value items in the raw user metadata?

Temp solution until chunking is improved. Avoid large key:value in the user data you save, and avoid saving lots of user data.

@Raidus
Copy link

Raidus commented Jan 25, 2024

Same issue here. Any update on the issue?

@dantrain
Copy link

Until the chunking is fixed I found a way around this by gzipping the chunk values like this in the setter:

zlib.gzipSync(Buffer.from(value, "utf-8")).toString("base64url")

and in the getter the reverse:

zlib.gunzipSync(Buffer.from(value, "base64url")).toString("utf-8")

This seems to make them short enough to work for me, YMMV.

@thibistaken
Copy link

Same issue trying the PKCE email and oauth flows with Supabase SSR. Any update? Thanks!

@charislam
Copy link

@thibistaken which version of @supabase/ssr are you on? There was a fix in 0.1.0 related to this

@thibistaken
Copy link

I just upgraded from 0.0.5 to 0.1.0 and it seems it is working now? Will test it out a bit more. Thanks @charislam!

@mb21
Copy link

mb21 commented Mar 12, 2024

Am I right in assuming that we need the chunking only because we store so much stuff in the cookies, much of it redundant information? Wouldn't it be enough to store only the access token and refresh token? All the other info can be derived from that server-side?

@yulluone
Copy link

@tobiassern the update you saw here was related to @supabase/auth-helpers and not @supabase/ssr. However we have now shipped this feature in the @supabase/ssr package too. But for SvelteKit there is a caveat in the createBrowser where you need to setup the cookies.get to handle chunking. I will add this to the guides soon.

Thank you for this,

I had been struggling with Google OAuth not working for hours, once I narrowed it down to a cookie-setting issue (the cookie was too large)... I came across this issue... A @supabase/ssr update from 0.0.5 to 0.3.0 fixed the issue.

@contactjavas
Copy link

Currently, this issue still exists even with latest supabase-js and supabase-ssr.
The effective solution for now is to minimalize the data in user_metadata field.

@gludington
Copy link

Following up mb21's earlier comment, is there an ability to configure/whitelist claims that go to the client (and therefore the cookie) to a minimal set, so that it is present in postgres for use, but not emitted to the client? Size aside, some of the information in that cookie might test the boundaries of what GDPR would consider "strictly necessary."

@teamclouday
Copy link

I have a socketio setup that connects to a python server which uses websockets. Apparently there's a hard limit of cookie size in header (8k) and my client keeps getting disconnected because of the large auth tokens created by supabase auth. Really hope there's a way to reduce the size.

@yekta
Copy link

yekta commented Aug 29, 2024

We are having the same issue with supabase/ssr. This not only breaks Nginx default config but also breaks Cloudflare. Some users have 2 chunks, some have 4. Even 2 chunks is dangerously close to standard header size limit when combined with other mid-sized cookies.

@oldbettie
Copy link

This seems to be a consistent issue. Why don't you store just the access_token, refresh_token in the original cookie and any other stuff can just do in cookie-name.1???? that seems pretty logical and simple it would not break everytime it chunks the cookie

@danperks
Copy link

danperks commented Oct 8, 2024

I'm using Nuxt, and I've just gone through and updated all my project dependencies to the latest version.
Interestingly, I wasn't having this issue before, but seemingly at random, I'm getting "Bad Request" errors stating my request header field exceeds server limit from NGINX.

Seems to match @yekta's issue, and this is all on the latest versions of packages.

EDIT: This is now a pretty critical issue for me, as it seems both Cloudflare and my NGINX reverse proxy are trashing requests with a cookie that is too long.

@serhii-kucherenko
Copy link

Same issue here. Nextjs just stops processing requests.
Any updates on how to fix it?

@oof2win2
Copy link

oof2win2 commented Nov 18, 2024

Same happens to me here. Vercel middleware is fully discarding all requests - there's too much data across all cookies combined and Vercel just discards the request

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.