supabase / supabase-js

An isomorphic Javascript client for Supabase. Query your Supabase database, subscribe to realtime events, upload and download files, browse typescript examples, invoke postgres functions via rpc, invoke supabase edge functions, query pgvector.
https://supabase.com
MIT License
3.27k stars 271 forks source link

Passed cookies with a different supabase url should be cleaned when passed to the supabase js client. #1314

Open JungeWerther opened 1 week ago

JungeWerther commented 1 week ago

Disclaimer not sure if feature or bug.

Bug report

Describe the bug

I am migrating my supabase project because I wanted to change the main region (to reduce latency between backend apis).

In the process, my supabase url changed. However, I'm unable to authenticate users on my staging environment, because the header size for requests sent to my middleware (running on Vercel) exceed a maximum threshold of 16kb. This is because cookies persist of both the old and the new project.

As an individual, this is easily solved by deleting old cookies. However, I will not request the same of my existing users.

The only way I see so far is to check the existing cookies that get passed in the first request, check whether their project-url is different from the one defined in my environment variables, and send a request from the server to delete existing old cookies on the old domain, before adding new cookies on the new domain.

This could be IMO a feature of the supabase client.

I think the existing size of auth cookies is a bit of an issue, also in the future. The provider tokens are really huge, and encode a LOT of information that is unnecessary for the main use case of the JWTs which is identifying a user.

I know you can add custom JWT claims but it is quite complex - in my opinion the default should be passing minimal information, then when a dev wants to pass more metadata on each request they still have the option to add it.

image

JungeWerther commented 1 week ago

Right now I found a workaround by defining

  const badCookie = ({ name }: RequestCookie) =>
    name.startsWith('sb-') &&
    !name.includes(
      new URL(process.env.NEXT_PUBLIC_SUPABASE_URL!).hostname.split('.')[0],
    )

and then

  const response = await updateSession<Database>(request)

  for (const cookie of request.cookies.getAll()) {
    if (badCookie(cookie)) {
      response.cookies.delete(cookie.name)
    }
  }

  return response

Such that cookies from the old project get deleted. Not a general solution though, only if you're on NEXTJS.