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

Next14 & @supabase/ssr: AuthApiError: invalid flow state, no valid flow state found #705

Closed lukerep closed 6 months ago

lukerep commented 6 months ago

Bug report

Describe the bug

My src/app/auth/callback/route.ts file looks like so:

import { createServerClient, type CookieOptions } from "@supabase/ssr";
import { cookies } from "next/headers";
import { type NextRequest, NextResponse } from "next/server";
import { env } from "~/env";

export async function GET(request: NextRequest) {
  const { searchParams, origin } = new URL(request.url);
  const code = searchParams.get("code");
  // if "next" is in param, use it as the redirect URL
  const next = searchParams.get("next") ?? "/";

  if (code) {
    const cookieStore = cookies();
    const supabase = createServerClient(
      env.NEXT_PUBLIC_SUPABASE_URL,
      env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
      {
        cookies: {
          get(name: string) {
            return cookieStore.get(name)?.value;
          },
          set(name: string, value: string, options: CookieOptions) {
            cookieStore.set({ name, value, ...options });
          },
          remove(name: string, options: CookieOptions) {
            cookieStore.delete({ name, ...options });
          },
        },
      },
    );
    const { error } = await supabase.auth.exchangeCodeForSession(code);
    if (!error) {
      return NextResponse.redirect(`${origin}${next}`);
    }
  }

  // return the user to an error page with instructions
  return NextResponse.redirect(`${origin}/auth/auth-code-error`);
}

Seems like user_id is null in auth.flow_state table: image

Other people have reported the same problem.

To Reproduce

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

  1. Click login with Google
  2. Get redirected to Google with a selection of my accounts
  3. Select an account
  4. Get redirected to my /auth/callback endpoint with code query param and other params
  5. The error shown earlier is the result

Expected behavior

System information

litewarp commented 6 months ago

I'm having the same issue after being redirected back to my app. I get a 403 invaid flow state.

When I check my auth.flow_state table, the user_id's are missing as well.

image

lukerep commented 6 months ago

I ended up getting it working.

@litewarp Is your redirect URL going directly to your app or to your Supabase instance?

litewarp commented 6 months ago

@litewarp Is your redirect URL going directly to your app or to your Supabase instance?

To a route handler in my app -- http://localhost:3000/auth/callback

I wonder if this can't be used for first-time signup since there's no user yet?

lukerep commented 6 months ago

@litewarp You need to point it to your supabase: http://localhost:54321/auth/v1/callback

Example config.toml

[auth.external.google]
enabled = true
client_id = "env(SUPABASE_AUTH_EXTERNAL_GOOGLE_CLIENT)"
secret = "env(SUPABASE_AUTH_EXTERNAL_GOOGLE_SECRET)"
# Overrides the default auth redirectUrl.
redirect_uri = "http://localhost:54321/auth/v1/callback"

and

[auth]
enabled = true
# The base URL of your website. Used as an allow-list for redirects and for constructing URLs used
# in emails.
site_url = "http://localhost:3000"
# A list of *exact* URLs that auth providers are permitted to redirect to post authentication.
additional_redirect_urls = ["http://localhost:54321/auth/v1/callback"]

Then in your auth component when signing in with OAuth it should look like this:

const handleSignInWithGoogle = async () => {
    await supabase.auth.signInWithOAuth({
      provider: "google",
      options: {
        redirectTo: `${location.origin}/auth/callback`, // This redirects to your NextJS route
        queryParams: {
          access_type: "offline",
          prompt: "consent",
        },
      },
    });
  };

Make sure you register http://localhost:54321/auth/v1/callback in your Google OAuth callback/redirect

litewarp commented 6 months ago

Got it working! Thanks!

vichu259 commented 2 weeks ago

I am facing the same issue.

async function GET(request: Request) {
    const { searchParams, origin } = new URL(request.url)
    const code = searchParams.get('code')
    // if "next" is in param, use it as the redirect URL
    const next = searchParams.get('next') ?? '/'

    if (code) {
      const supabase = serverClient();
      const { data, error } = await supabase.auth.exchangeCodeForSession(code);

      console.log("Exchange Code Response:", data); // Log the response data

      if (!error) {
          console.log("Exchange Code Successful");
          console.log("Redirecting to:", origin);
          return NextResponse.redirect(origin);
      } else {
          console.error("Error during code exchange:", error); // Log the error
      }
  } else {
      console.error("Authorization code missing or invalid"); // Log missing or invalid code
  }
    // return the user to an error page with instructions
    return NextResponse.redirect(`${process.env.AUTH_URL}/auth/auth-code-error`)
  }

exhange was successful but the there GET callback was failing. Not sure what the issue is.

2024-06-19T22:39:39Z [web] : Error: ⨯ AuthApiError: invalid flow state, no valid flow state found at handleError (webpack-internal:///(rsc)/./node_modules/@supabase/auth-js/dist/module/lib/fetch.js:74:11) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async _handleRequest (webpack-internal:///(rsc)/./node_modules/@supabase/auth-js/dist/module/lib/fetch.js:117:9) at async _request (webpack-internal:///(rsc)/./node_modules/@supabase/auth-js/dist/module/lib/fetch.js:99:18) at async SupabaseAuthClient._exchangeCodeForSession (webpack-internal:///(rsc)/./node_modules/@supabase/auth-js/dist/module/GoTrueClient.js:420:33) at async eval (webpack-internal:///(rsc)/./node_modules/@supabase/auth-js/dist/module/GoTrueClient.js:741:28) { __isAuthError: true, status: 404, code: 'flow_state_not_found' }

Could you help me?

eposha commented 1 week ago

Same issue with next js

bookerlyio commented 5 days ago

same issue