Closed probablykasper closed 1 year ago
I am also seeing this with using google oauth. Our initiation of the auth flow is on the client and I am seeing this error on the server, not sure if that is important.
I ran into this error earlier and the issue was caused by not passing the response from the sign in process to the callback request and using it to create the client, as shown in the docs.
So from:
// Start sign in with one-time password
const { error } = await supabase.auth.signInWithOtp({
email: 'foo@example.com',
options: {
emailRedirectTo: 'http://localhost:3000/api/auth/callback',
},
})
To:
// api/auth/callback
import { NextApiRequest, NextApiResponse } from 'next'
import { createServerSupabaseClient } from '@supabase/auth-helpers-nextjs'
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
// Create authenticated Supabase Client
const supabase = createServerSupabaseClient(
{ req, res },
{
supabaseUrl: SUPABASE_URL,
supabaseKey: SUPABASE_ANON_KEY,
}
)
I am running into this with createRouteHandlerSupabaseClient
(which is the same as createServerComponentSupabaseClient) that only takes headers
and cookies
, maybe something is lacking there?
I am also seeing this with using google oauth. Our initiation of the auth flow is on the client and I am seeing this error on the server, not sure if that is important.
Seeing exactly the same thing (client-initiated Google PKCE failing on exchangeCodeForSession
on the server). The code
returned from Google looks fine and is being passed to await supabase.auth.exchangeCodeForSession(code)
, so this must have something to do with the code verifier.
The issue in the code seems to be the use of two different clients. You are using the auth helpers along with the normal supabase client, this won't work and will result in the error you are getting. We have a branch of the auth-helpers with PKCE support that you should use until we make the final release. You can install this using:
npm install @supabase/auth-helpers-sveltekit@next
You shouldn't mix the auth-helpers client with a normal supabase-js client unless you are planning to do things with the service_role
key. There is an example project using these at the moment in this repo https://github.com/supabase-community/supabase-by-example/tree/next/magic-link/sveltekit. We will be releasing the next version of the auth-helpers with full support soon. Currently we are just finalising the documentation for release.
Yes, this was exactly my issue. Using 0.2.0-next.3 I've now moved on to a new error: AuthApiError: invalid flow state, no valid flow state found
@KrisBraun do you have a repo somewhere that I can check out the code? I'm still thinking there is a mix going on with the supabase-js client libraries.
@silentworks To avoid confusing the original issue here, I've created https://github.com/supabase/auth-helpers/issues/549. The issue seems to be related to exchangeCodeForSession
expecting user_id
to be set in the flow state. It's unclear to me how that would be, since this is the initial login, so no user has been created yet.
@silentworks I was mixing clients and what you suggested did fix it for me locally, but I'm still getting the error on Vercel unfortunately
@probablykasper thats likely due to either incorrect version being installed on Vercel or your code is cached on there somehow. Try deploying the fixed version to a new Vercel setup and report back here if there are still errors.
That was my suspicion as well, but no luck. The lockfile does use 0.10.0-next.3
- tried redeploying without build cache, pushing new commits and visiting the commit-specific deployment domain doesn't work
@probablykasper I'm going to make a big ask of you, but can you create a minimal reproducible example repo that I can take a look at please?
I tried reproducing it with the new 0.10.0 version, and the issue wasn't there. I'll let you know once I figure out more!
I played with this in the debugger and found a reliable repro. The blog post also confirms the following flow:
signInWithOTP
gets called with a redirect, usually the project's /auth/callback
sb-<project ID>-auth-token-code-verifier
/auth/callback
with the code
query param"Another client" cold mean an incognito window, another browser, another device, etc. E.g. someone initiated sign in from the browser on a desktop, then open the magic link from a mobile email app. Or initiated from the main browser app, but continued in a webview with a separate cookies store.
If I understand correctly, the code verifier shouldn't leave the client (that's the whole point of PKCE). So the fix here would just be failing gracefully from Supabase/GoTrue, and let the project display a recovery path. Something shorter than
Looks like you requested sign in from another device.
Open this page in Chrome on Windows
– or –
Sign in with another magic link on this iPhone
Workaround for now is to catch it (as it's not returned via result.error
)
Edit: Example with screenshots and code added here: https://github.com/supabase/auth-helpers/issues/545#issuecomment-1666960329
Is there a way to use PKCE easily with Cloudflare Workers? We've been using createClient
(from @supabase/supabase-js
) and it's been working great, until trying to add PKCE.
const supabase_client = createClient(c.env.SUPABASE_URL, c.env.SUPABASE_KEY, {
auth: {
persistSession: false,
flowType: 'pkce'
}
})
const token_test = 'asdfasdf-asdfasdf-adfsadf-asdfsdf' // We get the actual token from our URL manually elsewhere
const wat = await supabase_client.auth.exchangeCodeForSession(token_test);
AuthApiError: invalid request: both auth code and code verifier should be non-empty
at index.js:12757:18 {
__isAuthError: true,
name: AuthApiError,
status: 400,
stack: AuthApiError: invalid request: both auth code and …fier should be non-empty
at index.js:12757:18,
message: invalid request: both auth code and code verifier should be non-empty
}
I am having this exact issue, but only when I run npm run dev --host
and open the page from my mobile device (or a laptop using the hosted IP). It works on production deployed to Vercel, works when running locally with npm run dev
and using localhost
but fails with this error when running from hosted development server (so when I use the IP instead of localhost).
I am using the code example from the documentation without much changes so the error is appearing on the callback page.
I thought that maybe I am missing the redirect URL configured in Supabase, but it's there.
SvelteKit @ 1.20.2 Svelte @ 3.59.1 Auth Helpers SvelteKit @ 0.10.1 Supabase JS @ 2.24.0
Issue for me is with email confirmation flow not oauth. Works fine locally. Should point out, it seems to actually confirm the email but throws an error.
This is happening on Vercel and it's kicking out:
- error AuthApiError: invalid request: both auth code and code verifier should be non-empty
at /var/task/.next/server/chunks/928.js:3374:24
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
__isAuthError: true,
status: 400
}
For now, I have worked around this simply by suppressing the offending function. This obviously isn't an ideal situation though:
try {
await supabase.auth.exchangeCodeForSession(code)
} catch (error) {}
The issue in the code seems to be the use of two different clients. You are using the auth helpers along with the normal supabase client, this won't work and will result in the error you are getting.
@silentworks, Is this mentioned anywhere in the docs? I spent pretty much all day today trying to get OAuth to work in SSR mode on a NextJS project with a refine.dev template and coming across this information earlier would have been incredibly helpful!
Also, the naming is rather misleading - auth-helpers
strikes more as an add-on to supabase-js and not so much a replacement.
I tried reproducing it with the new 0.10.0 version, and the issue wasn't there. I'll let you know once I figure out more!
Updating the auth helpers made the error go away for me @silentworks
I'm having the same error with @supabase/auth-helpers-remix^0.2.1
.
Same issue. Not able to reproduce it locally. Also, on Vercel, only some users are experiencing it :/ Using Next.js pages directory.
Thanks @tholder, probably gonna use this fix as well for now…
nb: I'm using App Router on NextJS 13.4.7
I did some digging this evening and found that my NextJS route handler is not receiving cookies when calling cookies()
.
I confirmed this by changing the route.ts
of the handler to a page.tsx
and checking the cookies, indeed finding that the sb-<id>-auth-token-code-verifier
key was present.
I noticed this because throughout my debugging, the cookie was in the client and was being seen by the middleware, yet the exception we're talking about was still thrown...
The problem I have now is that only Route Handlers and Server Actions can return cookies to the client, so using a Server Component will not be possible.
I'll share if I find a solution, but it seems this could be a NextJS issue rather than a Supabase issue?
Did some more digging... in an older YouTube video on the Supabase channel, the presenter describes that there is a bug in NextJS with GET
requests where cookies are not piped through! Here's to the point in the video where this is mentioned.
However, in a newer video, this seems to no longer be the case... I'm still experiencing empty cookies in NextJS 13.4.7, though :/
After much googling and trawling the Vercel's GitHub discussions/issues, I've not found a solution to this.
In the end, I've taken a hacky approach in my middleware to handle the auth cookie, since cookies are available there for every request. I feel there is probably a way to do this with a ServerComponent and Server Actions, but I've already lost too much time to this issue and I want to get back to developing my project.
This is what my middleware looked like now:
import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs'
import { NextResponse, NextRequest } from 'next/server'
import type { Database } from '@/supabase/database.types'
export async function middleware(req: NextRequest) {
const res = NextResponse.next()
const url = new URL(req.url)
const supabase = createMiddlewareClient<Database>({ req, res })
if (url.pathname === "/auth/callback") {
const code = url.searchParams.get('code')
if (code) {
await supabase.auth.exchangeCodeForSession(code)
}
} else {
await supabase.auth.getSession()
}
return res
}
Needless to say, this is not idea.
There are quite a few discussions/issues related to cookies in NextJS 13:
I couldn't find many that are exactly about cookies being missing:
So I made my own report with an example to clearly describe this exact case: https://github.com/vercel/next.js/issues/52209
Hi @ky1ejs,
For what it's worth, I'm also working with Next.js and I've did the following which works for me:
//app/auth/callback/route.ts
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs';
import { cookies } from 'next/headers';
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import type { Database } from '@/types/database.types';
import { ROUTES } from '@/consts';
export async function GET(request: NextRequest) {
const requestUrl = new URL(request.url);
const code = requestUrl.searchParams.get('code');
if (code) {
const supabase = createRouteHandlerClient<Database>({ cookies });
await supabase.auth.exchangeCodeForSession(code);
}
// URL to redirect to after sign in process completes
return NextResponse.redirect(`${requestUrl.origin}${ROUTES.accountNew}`);
}
Hope this helps 🎉
Turns out I need to upgrade to the latest version of Node 18.x: https://github.com/vercel/next.js/issues/52209#issuecomment-1621889571
@ky1ejs Thanks, that was a mystery working out why cookies were not not showing up
I'm still facing the issue. Followed the documentation https://supabase.com/docs/guides/auth/auth-helpers/sveltekit#server-side and I'm trying server side authentication.
Supabase auth logs are showing the same:
{"component":"api","error":"400: invalid request: both auth code and code verifier should be non-empty","level":"info","method":"POST","msg":"400: invalid request: both auth code and code verifier should be non-empty","path":"/token","referer":"","remote_addr":"
i'm also experiencing this error when i try to use the remix auth helpers following the official guide here.
using:
supabaseClient.auth.signInWithOtp
with auth email settings:
auth works fine out of the box with this remix stack, but i'd like to switch to the official remix helpers.
my solution was this, this worked for me perfectly
// middleware.ts in next.js
export default async function middleware(req: NextRequest) {
const res = NextResponse.next()
const url = new URL(req.url)
const supabase = createMiddlewareClient<Database>({ req, res })
await supabase.auth.getSession()
if (url.pathname == '/auth/callback') {
const code = url.searchParams.get('code')
if (code) {
try {
await supabase.auth.exchangeCodeForSession(code)
return NextResponse.redirect('http://app.localhost:3000/reset-password')
} catch (error) {
console.log(error)
}
} else {
return NextResponse.redirect('http://app.localhost:3000/login')
}
}
}
for anyone landing here using Remix, the fix that worked for me was to patch @supabase/auth-helpers-shared
and replace pkce
with implicit
for the flowType
values in both ESM and CJS exports.
this assumes you've followed the official guide.
for anyone landing here using Remix, the fix that worked for me was to patch
@supabase/auth-helpers-shared
and replacepkce
withimplicit
for theflowType
values in both ESM and CJS exports.this assumes you've followed the official guide.
That takes away the SSR aspect of things. That only work if you are doing your auth on the front end, which doesn't support the best Remix experience.
Is there a way to handle this issue if a user opens a verify/forgot password email and it is not on the same device as they sent it on? (e.g forgot password link sent on laptop, verifier cookie saved locally, user opens link on phone, verifier cookie not present)
Here's a possible flow. More code but better UX imo.
No client JS needed in this example. Should work with SSR and SSG.
As mentioned above, missing cookie/clicking from a different device is a normal case that should be handled imo.
Screenshots here. Code below.
Present login options
Show a quick tip after sending magic link
Green path: home page; missing cookie (this issue): show recovery options. Optionally, show other ways to login, e.g. password
Bonus (unrelated to this issue). If the link has been clicked or expired, return to login page with a message:
These messages can probably be improved if you work with a design team.
Update your login page support the above layouts. For example, use a type
query param with these values:
diff_device
bad_code
sent_magic_link
(optional)Update the emailRedirectTo
field when handling the "Sign in with magic link" button click.
You can do this on the client or the server.
const urlSafeEmail = encodeURIComponent(email);
await getServerActionSupabase().auth.signInWithOtp({
email,
options: {
emailRedirectTo: `${YOUR_BASE_URL}/auth/callback/${urlSafeEmail}`,
},
});
// Show the "magic link sent" layout here. Options:
// Server or client: redirect to `/YOUR_LOGIN_PATH?type=sent_magic_link&email=${urlSafeEmail}`
// Client: You can also use JS to show the message
Example route handler in Next.js:
// src/app/auth/callback/[email]/route.ts
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
import { cookies } from "next/headers";
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { isAuthApiError } from "@supabase/supabase-js";
type Props = {
params: { email: string };
};
export async function GET(request: NextRequest, { params }: Props) {
const requestUrl = new URL(request.url);
const code = requestUrl.searchParams.get("code");
if (!code) {
return redirectBadCode();
}
const supabase = createRouteHandlerClient({ cookies });
try {
const { data } = await supabase.auth.exchangeCodeForSession(code);
if (data.session) {
return NextResponse.redirect(`${requestUrl.origin}/YOUR_HOME_PATH`");
} else {
return redirectBadCode();
}
/* https://github.com/supabase/auth-helpers/issues/545
* When fixed, rm catch and use the error returned from exchangeCodeForSession(…)
*/
} catch (error) {
if (isAuthApiError(error)) {
return redirectDiffDevice();
}
// If you, too, like living dangerously:
throw error;
}
function redirectBadCode() {
const searchParams = encodeSearchParams({
email: params.email,
type: "bad_code",
});
return NextResponse.redirect(`${requestUrl.origin}/YOUR_LOGIN_PATH?${searchParams}`);
}
function redirectDiffDevice() {
const searchParams = encodeSearchParams({
email: params.email,
type: "diff_device",
});
return NextResponse.redirect(`${requestUrl.origin}/YOUR_LOGIN_PATH?${searchParams}`);
}
}
function encodeSearchParams(params: Record<string, string>) {
return new URLSearchParams(params).toString();
}
Bit more complicated to maintain but worth it for the overall UX imo.
Should work with other SSR/SSG frameworks too since the above doesn't need any client-side JS.
Share here if you found better ways 🙌
I was running into this issue as well running my app locally. When running locally, my host was http://something.localtest.me
. This issue was gone when going back to http://localhost
.
I ran into the same issue, I am using Supabase+Next.js auth helpers.
The code:
// invite_user.ts
import { NextResponse } from 'next/server'
import { signInWithMagicLink } from '@/utils/supabase-queries'
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs'
import { cookies } from 'next/headers'
export async function GET(request: Request) {
const supabase = createRouteHandlerClient<Database>({ cookies })
const { searchParams } = new URL(request.url)
const email = searchParams.get('email')
if (email) {
await signInWithMagicLink(supabase, email)
return NextResponse.json('Invite sent!')
}
return NextResponse.json('No email provided')
}
// supabase-queries.ts
import { SupabaseClient } from '@supabase/supabase-js'
import { toSiteURL } from './utils'
import { errors } from './errors'
export const signInWithMagicLink = async (
supabase: SupabaseClient<Database>,
email: string
) => {
const { error } = await supabase.auth.signInWithOtp({
email,
options: {
emailRedirectTo: toSiteURL('/auth/callback'),
},
})
if (error) {
errors.add(error.message)
throw error
}
}
// /auth/callback/route.ts
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs'
import { cookies } from 'next/headers'
import { NextResponse } from 'next/server'
export const dynamic = 'force-dynamic'
export async function GET(request: Request) {
const requestUrl = new URL(request.url)
const code = requestUrl.searchParams.get('code')
console.log('requestUrl', request.url)
console.log('code', code)
if (code) {
try {
const supabase = createRouteHandlerClient<Database>({ cookies })
await supabase.auth.exchangeCodeForSession(code)
} catch (error) {
console.error('Failed to exchange code for session: ', error)
}
}
const redirectTo = new URL('/required-session', requestUrl.origin)
return NextResponse.redirect(redirectTo)
}
I am getting the code
correctly from Supabase API:
requestUrl: http://localhost:3000/auth/callback?code=1aeb35ec-029b-494c-88d3-6ce887d86035
code: 1aeb35ec-029b-494c-88d3-6ce887d86035
But there is the same error:
Failed to exchange code for session: AuthApiError: invalid request: both auth code and code verifier should be non-empty
I ran into the same issue, I am using Supabase+Next.js auth helpers.
The code:
// invite_user.ts import { NextResponse } from 'next/server' import { signInWithMagicLink } from '@/utils/supabase-queries' import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs' import { cookies } from 'next/headers' export async function GET(request: Request) { const supabase = createRouteHandlerClient<Database>({ cookies }) const { searchParams } = new URL(request.url) const email = searchParams.get('email') if (email) { await signInWithMagicLink(supabase, email) return NextResponse.json('Invite sent!') } return NextResponse.json('No email provided') }
// supabase-queries.ts import { SupabaseClient } from '@supabase/supabase-js' import { toSiteURL } from './utils' import { errors } from './errors' export const signInWithMagicLink = async ( supabase: SupabaseClient<Database>, email: string ) => { const { error } = await supabase.auth.signInWithOtp({ email, options: { emailRedirectTo: toSiteURL('/auth/callback'), }, }) if (error) { errors.add(error.message) throw error } }
// /auth/callback/route.ts import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs' import { cookies } from 'next/headers' import { NextResponse } from 'next/server' export const dynamic = 'force-dynamic' export async function GET(request: Request) { const requestUrl = new URL(request.url) const code = requestUrl.searchParams.get('code') console.log('requestUrl', request.url) console.log('code', code) if (code) { try { const supabase = createRouteHandlerClient<Database>({ cookies }) await supabase.auth.exchangeCodeForSession(code) } catch (error) { console.error('Failed to exchange code for session: ', error) } } const redirectTo = new URL('/required-session', requestUrl.origin) return NextResponse.redirect(redirectTo) }
I am getting the
code
correctly from Supabase API:requestUrl: http://localhost:3000/auth/callback?code=1aeb35ec-029b-494c-88d3-6ce887d86035 code: 1aeb35ec-029b-494c-88d3-6ce887d86035
But there is the same error:
Failed to exchange code for session: AuthApiError: invalid request: both auth code and code verifier should be non-empty
I have the same issue but with social login did you find a solution? I'm using astro SSR btw.
I ran into the same issue, I am using Supabase+Next.js auth helpers. The code:
// invite_user.ts import { NextResponse } from 'next/server' import { signInWithMagicLink } from '@/utils/supabase-queries' import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs' import { cookies } from 'next/headers' export async function GET(request: Request) { const supabase = createRouteHandlerClient<Database>({ cookies }) const { searchParams } = new URL(request.url) const email = searchParams.get('email') if (email) { await signInWithMagicLink(supabase, email) return NextResponse.json('Invite sent!') } return NextResponse.json('No email provided') }
// supabase-queries.ts import { SupabaseClient } from '@supabase/supabase-js' import { toSiteURL } from './utils' import { errors } from './errors' export const signInWithMagicLink = async ( supabase: SupabaseClient<Database>, email: string ) => { const { error } = await supabase.auth.signInWithOtp({ email, options: { emailRedirectTo: toSiteURL('/auth/callback'), }, }) if (error) { errors.add(error.message) throw error } }
// /auth/callback/route.ts import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs' import { cookies } from 'next/headers' import { NextResponse } from 'next/server' export const dynamic = 'force-dynamic' export async function GET(request: Request) { const requestUrl = new URL(request.url) const code = requestUrl.searchParams.get('code') console.log('requestUrl', request.url) console.log('code', code) if (code) { try { const supabase = createRouteHandlerClient<Database>({ cookies }) await supabase.auth.exchangeCodeForSession(code) } catch (error) { console.error('Failed to exchange code for session: ', error) } } const redirectTo = new URL('/required-session', requestUrl.origin) return NextResponse.redirect(redirectTo) }
I am getting the
code
correctly from Supabase API:requestUrl: http://localhost:3000/auth/callback?code=1aeb35ec-029b-494c-88d3-6ce887d86035 code: 1aeb35ec-029b-494c-88d3-6ce887d86035
But there is the same error:
Failed to exchange code for session: AuthApiError: invalid request: both auth code and code verifier should be non-empty
I have the same issue but with social login did you find a solution? I'm using astro SSR btw.
Nope. Still struggling with this... :(
OK, I solved it partly — it works if I send a signup email with supabase.auth.signInWithOtp
in server component (a regular) page. I just tested with a server action and it works!
However, what doesn't work, and what I need for my use case is sending a signup email via API route.
So probably something is wrong with createRouteHandlerClient({ cookies })
, probably it's not setting a "code verifier" that is used later in callback route.
Can someone try sending a sign up email via API route with createRouteHandlerClient({ cookies })
and supabase.auth.signInWithOtp
to confirm it doesn't work?
OK, I solved it partly — it works if I send a signup email with
supabase.auth.signInWithOtp
in server component (a regular) page. I just tested with a server action and it works!However, what doesn't work, and what I need for my use case is sending a signup email via API route.
So probably something is wrong with
createRouteHandlerClient({ cookies })
, probably it's not setting a "code verifier" that is used later in callback route.
Can someone try sending a sign up email via API route with
createRouteHandlerClient({ cookies })
andsupabase.auth.signInWithOtp
to confirm it doesn't work?
Also still struggling with this. Pretty bad UX in my app and can't seem to get around the code verifier being stored locally.
I have the same issue on nextjs and supabase-auth-nextjs.
I have a workaround where I use authStateChange
on client-side. It doesn't break the UI/UX too much.
import { useEffect } from 'react';
import { createClientComponentClient } from '@supabase/supabase-js';
import { useRouter } from 'next/router';
export default function Home() {
const supabase = createClientComponentClient();
const router = useRouter();
useEffect(() => {
// Set up an authentication listener
const { data: { subscription } } = supabase.auth.onAuthStateChange(
async (event, session) => {
console.log(`Supabase auth event in home: ${event}`);
if (event === 'SIGNED_IN') {
// Redirect to the dashboard upon successful sign-in
router.push('/dashboard');
}
if (session !== null) {
// Redirect to the dashboard if a session is present
console.log('session is:', session);
router.push('/dashboard');
}
// Additional checks or redirects can be implemented
}
);
// Cleanup function: unsubscribe the auth listener when the component unmounts
return () => {
subscription.unsubscribe();
};
}, []);
return (
<div>
{/* Your home page content */}
</div>
);
}
We have published a new guide on how to handle this from the email perspective and framework side of things. This requires an email template change and a new endpoint in your application https://supabase.com/docs/guides/auth/server-side/email-based-auth-with-pkce-flow-for-ssr
If you are using the Supabase CLI and want to customize your email templates, you can do this now by following this guide https://supabase.com/docs/guides/cli/customizing-email-templates
We have published a new guide on how to handle this from the email perspective and framework side of things. This requires an email template change and a new endpoint in your application https://supabase.com/docs/guides/auth/server-side/email-based-auth-with-pkce-flow-for-ssr
If you are using the Supabase CLI and want to customize your email templates, you can do this now by following this guide https://supabase.com/docs/guides/cli/customizing-email-templates
Awesome! So, should app/auth/confirm
route with verifyOtp
be used from now on instead of app/auth/callback
with exchangeCodeForSession
like in other examples?
@edgarasben yes if you are doing any auth process that uses magic links (signUp, resetPasswordForEmail, inviteUserByEmail and signInWithOtp). If you plan on doing signInWithOAuth
in your app then you will still need the app/auth/callback
route.
@edgarasben yes if you are doing any auth process that uses magic links (signUp, resetPasswordForEmail, inviteUserByEmail and signInWithOtp). If you plan on doing
signInWithOAuth
in your app then you will still need theapp/auth/callback
route.
If I need both, and there is only one email template, will the /callback route be able to handle the updated email templates?
@edgarasben but signInWithOAuth
doesn't use email templates. You would still just have both endpoints in your project.
Closing this out as we now have a guide showing how to get around this issue:
https://github.com/supabase/supabase/pull/16728 https://github.com/supabase/supabase/pull/16683
Looks like the problem still continues for signInWithOAuth in nextjs@13.4.19. @silentworks
with the same code not getting any error if i use nextjs@13.4.7
error AuthApiError: invalid flow state, no valid flow state found
client component
const signInWithGithub = async () => {
await supabase.auth.signInWithOAuth({
provider: "github",
options: {
redirectTo: window.location.origin + "/auth/callback",
},
});
};
app/auth/callback/route.js
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
import { cookies } from "next/headers";
import { NextResponse } from "next/server";
export const dynamic = "force-dynamic";
export async function GET(request) {
const requestUrl = new URL(request.url);
const code = requestUrl.searchParams.get("code");
if (code) {
const supabase = createRouteHandlerClient({ cookies });
await supabase.auth.exchangeCodeForSession(code);
}
return NextResponse.redirect(requestUrl.origin);
}
Re-opening this issue as a number of users have reported it still happening.
Can anyone still experiencing this please also state the browser they are using along with Next version and if its app router or pages directory?
Re-opening this issue as a number of users have reported it still happening.
Can anyone still experiencing this please also state the browser they are using along with Next version and if its app router or pages directory?
@silentworks I encounter the same error with exchangeCodeForSession
with SvelteKit on Chrome, simply by following this official tutorial: https://supabase.com/docs/guides/auth/auth-helpers/sveltekit
The complete code for my src/routes/auth/callback/+server.ts
file is the following (adapted for TypeScript):
import type { SupabaseClient } from '@supabase/supabase-js';
import { redirect } from '@sveltejs/kit';
export const GET = async ({
url,
locals: { supabase }
}: {
url: URL;
locals: { supabase: SupabaseClient };
}) => {
const code = url.searchParams.get('code');
if (code) {
await supabase.auth.exchangeCodeForSession(code);
}
throw redirect(303, '/');
};
The error message: AuthApiError: invalid request: both auth code and code verifier should be non-empty
Bug report
Describe the bug
When calling
auth.exchangeCodeForSession(code)
this error is thrown:To Reproduce
Login callback handler:
This is how I'm starting the login:
Expected behavior
error
property, not thrown.Screenshots
If applicable, add screenshots to help explain your problem.
System information