auth icon indicating copy to clipboard operation
auth copied to clipboard

Flow State not found

Open Phil9l opened this issue 1 year ago • 21 comments

Bug report

  • [x] I confirm this is a bug with Supabase, not with my own application.
  • [x] I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

I am using self-hosted supabase with gotrue and next js for auth. A few users can't login to the app because they get redirected to the following page every time they try to sign in with google.

[GET] /auth/callback?next=%2F&error_description=Flow%20State%20not%20found&error=server_error status=307

I haven't found anything unusual about these users.

On the client side I call

            const { error } = await supabase.auth.signInWithOAuth({
              provider: "google",
              options: {
                redirectTo: `${window.location.origin}/auth/callback?next=${window.location.href}`,
                queryParams: {
                  access_type: "offline",
                  prompt: "consent",
                },
              },
            });

To Reproduce

I haven't found why it happens to these specific users. They are using mobile chrome and using the same auth flow as other users. They tried logging in using multiple different google accounts.

  1. Go to https://climbest.app/
  2. Click on login
  3. Be lucky I guess?
  4. Get redirected to the Flow State not found error.

Expected behavior

Users can log in to the app.

Screenshots

https://imgur.com/a/D9WGyMH

System information

  • User agent: Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36
  • OS: Android 10
  • Browser: Chrome 120
  • Version of supabase-js: 2.39.0
  • Version of Node.js: Node.js 18.x

Phil9l avatar Dec 11 '23 23:12 Phil9l

What libraries do you use with NextJS? Please send us a code snippet that includes the initialization of the Supabase client.

hf avatar Dec 19 '23 14:12 hf

What libraries do you use with NextJS?

    "@supabase/ssr": "^0.0.4",
    "@supabase/supabase-js": "^2.39.0",

Please send us a code snippet that includes the initialization of the Supabase client.

I'm initializing the client like this:

import { createBrowserClient } from "@supabase/ssr";

const supabase = createBrowserClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);

And using like this:

const { error } = await supabase.auth.signInWithOAuth({
  provider: "google",
  options: {
    redirectTo: `${window.location.origin}/auth/callback?next=${window.location.href}`,
    queryParams: {
      access_type: "offline",
      prompt: "consent",
    },
  },
});

I think I copy-pasted code from https://supabase.com/docs/guides/auth/server-side/oauth-with-pkce-flow-for-ssr to my climbclimb/src/app/auth/callback/route.ts:

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

export 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 cookieStore = cookies();
    const supabase = createServerClient(
      process.env.NEXT_PUBLIC_SUPABASE_URL!,
      process.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 });
          },
        },
      }
    );

    try {
      if (!code) {
        throw new Error(
          `code param is missing in ${
            request.url
          }; all params: ${JSON.stringify(searchParams)}`
        );
      }
      const { error } = await supabase.auth.exchangeCodeForSession(code);

      if (!error) {
        return NextResponse.redirect(`${next}`);
      } else {
        console.error(error);
        return NextResponse.redirect(`${origin}/?error=${error.message}`);
      }
    } catch (error: unknown) {
      console.log(error);
      if (error instanceof Error) {
        return NextResponse.redirect(`${origin}/?error=${error.message}`);
      } else {
        return NextResponse.redirect(`${origin}/?error=${error?.toString()}`);
      }
    }
  }

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

Phil9l avatar Dec 19 '23 17:12 Phil9l

I'm also experiencing the same thing. Some of my google user aren't able to login because of the same problem. @Phil9l were you able to get around this issue?

nonnster avatar Jan 17 '24 14:01 nonnster

I'm also experiencing the same thing. Some of my google user aren't able to login because of the same problem. @Phil9l were you able to get around this issue?

No, unfortunately, not. More and more users are complaining about it. It's getting pretty critical for us at this point.

Phil9l avatar Jan 17 '24 15:01 Phil9l

If you are able to reproduce, please send us a HAR recording if possible. You can use https://supabase.help if you want to keep that private, just mention this issue when opening a support ticket.

Some causes of why the error could be happening:

  1. Cookie chunking issues -- mobile browsers may be having trouble dealing with larger / multiple cookies.
  2. Requesting sign-in from one browser receiving the callback on another. (When using PKCE the sign-in should complete on the same browser it was started on.)
  3. The cycle takes too long. Right now this is 300 seconds.

As you mentioned self-hosting, please provide us with details of the versions you're using on the server and configuration options related to this.

hf avatar Jan 19 '24 14:01 hf

We have seen that too, but only occasionally and I cannot reproduce that (hence can't share more than just these):

TypeError: Cannot read properties of undefined (reading 'call')
    at Object.__webpack_require__ [as require] (/var/task/.next/server/webpack-runtime.js:1:161)
    at /var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:111:463
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async rs (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:110:4701)
    at async rT (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:111:27761)
    at async ee (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:16:24526)
    at async en.responseCache.get.incrementalCache (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:17:991)
    at async rW.renderToResponseWithComponentsImpl (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:17:448)
    at async rW.renderPageComponent (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:17:4990)
    at async rW.renderToResponseImpl (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:17:5573)
[POST] /auth/login?error=server_error&error_description=Flow%20State%20not%20found&next=%2Fquestion-suggestion status=500

image

hnykda avatar Feb 20 '24 21:02 hnykda

Hey, I am experiencing the same issue. I got this callback URL, unable to replicate it on my side. It was spotted on Pagesense logs.

#error=server_error&error_code=422&error_description=Flow+state+not+found

JeronimasDargis avatar May 30 '24 16:05 JeronimasDargis

We're also seeing this, it's happening 20-40 times a day for our users. Redirect looks like this:

/error?error=server_error&error_code=422&error_description=Flow+state+not+found&message=Missing+cod
e#error=server error&error code=422&error_description=Flow+state+not+found

jayhickey avatar May 31 '24 02:05 jayhickey

Same for us, didn't see any issue like for months, started to happening last week...

Forsect avatar Jun 01 '24 19:06 Forsect

Same for us, google oauth suddenly doesn't work 30% of the time.

Mostly for mobile users but also happens on Desktop.

Jaaneek avatar Jun 01 '24 19:06 Jaaneek

We're noticing this same trend in our project using Google Auth. I would greatly appreciate if Supabase can provide us with some guidance.

gvzq avatar Jun 18 '24 19:06 gvzq

I'm getting this when trying to confirm emails using a callback url

const { error } = await supabase.auth.exchangeCodeForSession(code);

bookerlyio avatar Jun 30 '24 19:06 bookerlyio

I have the same problem, as auth-code a uuid v4 is expected, but from the provider I only get back a code (i.e. ANbOebvxVXCktJlSDXTU) which is not found in the DB (obviously), I don't know where the uuid v4 should come from that is searched for in https://github.com/supabase/auth/blob/master/internal/api/token.go#L258

xeladotbe avatar Jul 01 '24 18:07 xeladotbe

Hey team(s),

Thanks for flagging this and for patiently waiting. Flow State not found typically indicates that one should restart the flow as the internal db representation containing the matching code doesn't seem to exist. It tends to be a generic error which can arise for a spread of reasons. We're looking to see if there's a common overarching cause though.

With respect to the individual queries could we trouble everyone for a few information.

I have the same problem, as auth-code a uuid v4 is expected, but from the provider I only get back a code (i.e. ANbOebvxVXCktJlSDXTU) which is not found in the DB (obviously), I don't know where the uuid v4 should come from that is

For clarity, the Auth Code in this case is returned by Supabase Auth and not the OAuth provider (e.g. Google). It's returned as a param ?code=<...> once the call to supabase.auth.signInWithOAuth has completed. Could you try using the code returned from signInWithOAuth or similar and let us know if there are any issues?

We're noticing this same trend in our project using Google Auth. I would greatly appreciate if Supabase can provide us with some guidance. Same for us, didn't see any issue like for months, started to happening last week... We're also seeing this, it's happening 20-40 times a day for our users. Redirect looks like this:

Would the respective team(s) be able to provide additional reproduction steps for this? If there's sensitive information feel free to open a ticket via our support line

Thanks! Let us know if there are any pressing concerns.

J0 avatar Jul 03 '24 14:07 J0

Hey @Jaaneek

Thanks for the report - do you recall if there's a specific reproducible scenario where this happens? We'd like to dig in further.

Same for us, google oauth suddenly doesn't work 30% of the time. Mostly for mobile users but also happens on Desktop.

J0 avatar Jul 03 '24 14:07 J0

~~help same issue, kakao provider too~~ --- i handle it

In my case, the error occurred because Nginx received a header from Google that was too large to process

kor-bim avatar Jul 10 '24 11:07 kor-bim

~help same issue, kakao provider too~ --- i handle it

In my case, the error occurred because Nginx received a header from Google that was too large to process

In my case this works. You just saved my life thank you.

msssrp avatar Jul 14 '24 08:07 msssrp

We recently discovered that users clicked twice on the Google OAuth confirmation page, causing issues. The first click successfully triggers Supabase's /callback, but the second click fails because /callback deletes the flow state ID after the initial successful call.

By the way, I'm using the Supabase cloud not self-hosted.

@J0

hotay avatar Jul 18 '24 03:07 hotay

Thanks @hotay this is useful

J0 avatar Jul 18 '24 08:07 J0

After supabase.auth.exchangeCodeForSession I returned a page that performed a redirect, when I just return return NextResponse.redirect(requestUrl.origin); the problem goes away. I suspect its a race condition with setting/reading the cookie

kirkstrobeck avatar Jul 20 '24 22:07 kirkstrobeck

What I realized was happening in my case is that during sign up, resource creation was taking longer than 5 seconds, so the oauth callback was retried. The retried request always failed with this error since I assume the code was already read/processed. I'm using Remix, so I ended up running async functions in parallel to speed up my loader and using Streaming for a better UX.

chris-feist avatar Aug 08 '24 04:08 chris-feist