supabase / auth-helpers

A collection of framework specific Auth utilities for working with Supabase.
https://supabase.github.io/auth-helpers/
MIT License
893 stars 240 forks source link

Issue with @supabase/ssr and Nextjs v14.0.4 #703

Closed C-Johanson closed 5 months ago

C-Johanson commented 6 months ago

Bug report

Describe the bug

I have a project on Nextjs 14.0.3 with a working supabase auth flow, setting and reading cookies fine. I started a new nextjs project with create-next-app@latest and Next seesm to have pushed a new ver. After setting up all of the supabase auth identically to the project before, I kept getting this error using @supabase/ssr

 ⨯ TypeError: Cannot read properties of undefined (reading 'auth')
    at readUserSession (./lib/supabase/actions.ts:46:36)
    at async NavBar (./components/NavBar.tsx:28:22)
digest: "2431425738"
  35 |     const supabase = await getServerClient()
  36 |
> 37 |     const session = await supabase.auth.getSession()
     |                                   ^
  38 |
  39 |     return session
  40 | }

getServerClient() is as follows:

export async function getServerClient() {
    'use server'

    const cookieJar = cookies()
    const options: SupabaseClientOptions<"public"> = { auth: {flowType: 'pkce'}}

    const supabase = createServerClient(
      process.env.NEXT_PUBLIC_SUPABASE_URL!,
      process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,

      {
        // ...options,
        cookies: {
          get(name: string) {
            return cookieJar.get(name)?.value
          },
          set(name: string, value: string, options: CookieOptions) {
            try {
                cookieJar.set({ name, value, ...options })
            } catch {

            }
          },
          remove(name: string, options: CookieOptions) {
            try {
                cookieJar.set({ name, value: '', ...options })
            } catch {

            }
          },
        },
      }
    )

    return supabase
}

and this is the function throwing the error:

export async function readUserSession() {
    const supabase = await getServerClient()

    const session = await supabase.auth.getSession()

    return session
}

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Create a next app with create-next-app@latest
  2. Set up supabase auth
  3. try to use supabase = createServerClient(...) and then any supabase.auth method

    Expected behavior

Expected to be able to get auth client from supabse

Screenshots

If applicable, add screenshots to help explain your problem.

System information

kangmingtay commented 6 months ago

@C-Johanson that's indeed strange, i'm unable to reproduce this - do you happen to have a repo that i can clone to see what's going wrong here?

also, have you tried console logging the supabase object returned from getServerClient() as a sanity check ?

pstachula-dev commented 6 months ago

'use server' - it looks like the problem , could you remove this?

dijonmusters commented 5 months ago

I may have misunderstood what is going on, but it looks like you're trying to return a Supabase client from a Server Actions. This is not possible as it is too complex an object to be serialized. Additionally, you need to create the Supabase client from the scope of the Server Component as calling the cookies function at this level signals to Next.js that this route is dynamic.

Shorter answer: there is a lot of configuration that needs to line up perfectly. Therefore, we recommend using the with-supabase template for all Next.js and Supabase projects. This can be used when creating a new project with create-next-app:

npx create-next-app@latest -e with-supabase

The main benefit of using this as a starting point, is all of the server-side auth and PKCE stuff is already configured for you.