Next14 & @supabase/ssr: AuthApiError: invalid flow state, no valid flow state found
lukerep opened this issue · comments
Bug report
- I confirm this is a bug with Supabase, not with my own application.
- I confirm I have searched the Docs, GitHub Discussions, and Discord.
Describe the bug
- When using the Google Oauth provider, after being redirected from Google I receive the following error:
⨯ AuthApiError: invalid flow state, no valid flow state found
at handleError (webpack-internal:///(rsc)/./node_modules/@supabase/gotrue-js/dist/module/lib/fetch.js:45:11)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async _handleRequest (webpack-internal:///(rsc)/./node_modules/@supabase/gotrue-js/dist/module/lib/fetch.js:92:9)
at async _request (webpack-internal:///(rsc)/./node_modules/@supabase/gotrue-js/dist/module/lib/fetch.js:72:18)
at async SupabaseAuthClient._exchangeCodeForSession (webpack-internal:///(rsc)/./node_modules/@supabase/gotrue-js/dist/module/GoTrueClient.js:403:33)
at async eval (webpack-internal:///(rsc)/./node_modules/@supabase/gotrue-js/dist/module/GoTrueClient.js:824:28) {
__isAuthError: true,
status: 403
}
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:
Other people have reported the same problem.
To Reproduce
Steps to reproduce the behavior, please provide code snippets or a repository:
- Click login with Google
- Get redirected to Google with a selection of my accounts
- Select an account
- Get redirected to my
/auth/callback
endpoint withcode
query param and other params - The error shown earlier is the result
Expected behavior
- The user is logged in successfully via Google Oauth
System information
- OS: [Windows]
- Browser [chrome]
- Version of supabase-js: [2.39.0]
- Version of supabase/ssr: [0.0.10]
- Version of NextJS [14.0.3]
- Version of Node.js: [18.19.0]
I ended up getting it working.
@litewarp Is your redirect URL going directly to your app or to your Supabase instance?
@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?
@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
Got it working! Thanks!
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?
Same issue with next js
same issue