supabase / auth-helpers

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

invalid request: both auth code and code verifier should be non-empty #545

Closed probablykasper closed 1 year ago

probablykasper commented 1 year ago

Bug report

Describe the bug

When calling auth.exchangeCodeForSession(code) this error is thrown:

AuthApiError: invalid request: both auth code and code verifier should be non-empty
    at /Users/k/git/myrepo/node_modules/@supabase/gotrue-js/dist/main/lib/fetch.js:41:20
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  __isAuthError: true,
  status: 400

To Reproduce

Login callback handler:

const code = event.url.searchParams.get('code')
if (typeof code === 'string') {
  const { data, error } = await event.locals.supabase.auth.exchangeCodeForSession(code)
}

This is how I'm starting the login:

const supabaseAnonPkce = createClient<Database>(
    PUBLIC_SUPABASE_URL,
    PUBLIC_SUPABASE_ANON_KEY,
    {
        auth: {
            flowType: 'pkce',
        },
    }
)
const { error } = await supabaseAnonPkce.auth.signInWithOtp({
    email,
})

Expected behavior

Screenshots

If applicable, add screenshots to help explain your problem.

System information

Alex-Yakubovsky commented 1 year ago

For those using Remix (and likely other frameworks). One potential cause is that you're not forwarding the Set-Cookie header to your client from your supabase.auth.signUp(...) server side call, which sets the verifier code for the PKCE flow. If you're using remix, you're probably creating a signup within an action

// app/routes/sign-up.tsx
import { createServerClient } from "@supabase/auth-helpers-remix";

export async function action({ request, context }) {
   const response = new Response()
     const supabase = createServerClient(
    SUPABASE_URL,
    SUPABASE_ANON_KEY,
    {
      request,
      response,
      cookieOptions: {
        name: context.env.SUPABASE_COOKIE_NAME,
      },
    },
  );

   await supabase.auth.signUp({ ... }) // this updates the `response` headers

   // or redirect(..., { headers: response.headers })
   return json(..., { headers: response.headers })
}

Double check in your dev tools that a cookie named something like supabase_verifier_code is set in your browser (the implication being that you have to redeem the auth code in the same browsers that issued the signup).

gursheyss commented 1 year ago

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

Exact same issue here

z-x commented 1 year ago

Also still expecting this using SvelteKit and following the guide from the official docs 1:1 and then using npm dev --host and using the IP in the browser instead of localhost. Logging in using OAuth, doesn't matter which one.

AuthApiError: invalid request: both auth code and code verifier should be non-empty
silentworks commented 1 year ago

@z-x your issues is related to you using the IP address and your browser not being able to read the cookie. If anyone else is doing this you need to setup your cookieOptions correctly when using --host in order to use IP address instead.

silentworks commented 1 year ago

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

@vinch is this with magic links or OAuth? If magic links we have a guide on how to resolve this https://supabase.com/docs/guides/auth/server-side/email-based-auth-with-pkce-flow-for-ssr. @Alex-Yakubovsky this guide would also be the same for Remix too.

silentworks commented 1 year ago

I've tested this again in my setup using SvelteKit with OAuth and cannot replicate what folks are reporting here. It's best one of your provide a minimal reproducible example repository otherwise I won't be able to help much with this. My test OAuth projects are all here for the framework of your choice https://github.com/supabase-community/supabase-by-example/tree/main/oauth-flow

https://github.com/supabase/auth-helpers/assets/79497/892f8c09-4729-429e-9f7a-8a57751febc0

nilooy commented 1 year ago

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);
}

i am also having same issue, with all latest version supabase js, auth helpers and same code

silentworks commented 1 year ago

I'm going to close this issue again until someone actually provides an reproducible example repo as I've showed in my recording and examples I've linked. This is working but folks keep on adding on here I have the same issue without any reproducible examples.

mennankara commented 1 year ago

Repro is easy, just do a resetPasswordForEmail from your desktop, and click the update password link from your mobile.

ErwinAI commented 1 year ago

@silentworks My reproduction (https://github.com/nuxt-modules/supabase/issues/262#issuecomment-1722413056) using nuxtjs/supabase may be of interest. This reproduction is for a reset password flow. Particularly the SPA method exposes some extra detail. I suspect this particular network request is causing the error:

Failed to load resource: the server responded with a status of 403 ()
https://<id>.supabase.co/auth/v1/token?grant_type=pkce"

{
  code: 403
  msg: "code challenge does not match previously saved code verifier"
}  

Could be a bug in nuxtjs/supabase, though. Not sure. Unfortunately for me this bug is blocking and means I will have to migrate to a different platform :(

ErwinAI commented 1 year ago

@silentworks I've cloned https://github.com/supabase-community/supabase-by-example/tree/main/reset-flow/nuxt and set it up according to the readme file. The only deviation is that I use a https://.supabase.co URL / cloud hosted instead of a local instance of Supabase. Shouldn't matter though as far as I know.

I can reproduce the problem where I get the above result:

Failed to load resource: the server responded with a status of 403 ()
https://<id>.supabase.co/auth/v1/token?grant_type=pkce"

{
  code: 403
  msg: "code challenge does not match previously saved code verifier"
}  

OS: Windows 11 Browser: Chrome 116.0.5845.190 (Official Build) (64-bit) Node: v18.12.1

silentworks commented 1 year ago

@ErwinAI you will need to raise that with the Nuxt team as they manage the Nuxt Supabase integration. The solution is outlined here https://supabase.com/docs/guides/auth/server-side/email-based-auth-with-pkce-flow-for-ssr but unfortunately Nuxt works a bit different when it comes to the server compared to other SSR frameworks. Also note the issue is due to you requesting the reset in one browser/device and then clicking the link on another device, this is not permitted when using the pkce auth flow. The link I've added above addresses this.

silentworks commented 1 year ago

Repro is easy, just do a resetPasswordForEmail from your desktop, and click the update password link from your mobile.

@mennankara please read existing comments before adding new ones, I've added a link in previous comments on how to address this https://supabase.com/docs/guides/auth/server-side/email-based-auth-with-pkce-flow-for-ssr, if you aren't doing this then it won't work.