supabase / auth-helpers

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

Invalid Refresh Token: Refresh Token Not Found #436

Open bukinoshita opened 1 year ago

bukinoshita commented 1 year ago

Bug report

Describe the bug

I'm currently getting Invalid Refresh Token: Refresh Token Not Found error in my Next.js middleware

const res = NextResponse.next();
  const supabase = createMiddlewareSupabaseClient({ req, res });

  const {
    data: { session },
    error,
  } = await supabase.auth.getSession();

  if (error) {
    throw new Error(error.message);
  }

A clear and concise description of what the bug is.

To Reproduce

I think the issue is pretty similar to this one:

https://github.com/supabase/gotrue-js/issues/323 Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Go to '…'
  2. Click on '…'
  3. Scroll down to '…'
  4. See error

Expected behavior

To logout the user, or keep them signed in

A clear and concise description of what you expected to happen.

Screenshots

If applicable, add screenshots to help explain your problem.

System information

Additional context

Add any other context about the problem here.

imownbey commented 1 year ago

This is also happening for me after switching to SSR from auth helpers. The behavior is the middleware will throw a refresh token not found error and log the user out. The refresh token was not used by anything else already as far as I know. It happens for example when coming back to my computer in the morning, or just when loading local or prod after a couple of hours.

imownbey commented 1 year ago

This is reproducible with a local supabase with jwt_expiry turned down to 60 (or some other low number) and the default app created with npx create-next-app -e with-supabase. The first refresh goes fine, although 10 refresh tokens get created: Here is refresh_tokens table before the initial refresh: image Here it is after first refresh: image And then refreshing again the table stays the same and you get a ton of these errors. Here are the debugger logs debugger_output.txt

At that point you get logged out of the app.

imownbey commented 1 year ago

I posted a fix for this in https://github.com/supabase/auth-helpers/issues/691

devbydaniel commented 1 year ago

Found this thread after encountering the same error following the official docs here: https://supabase.com/docs/guides/auth/auth-helpers/nextjs#managing-session-with-middleware

As was already described by others, the error happens after being inactive some time.

I posted a fix for this in #691

Nothing against the code, but this looks more like a workaround than an actual fix, right? 😅

I don't understand the underlying mechanism in detail, but I'd expect something like this to work:

export async function middleware(req: NextRequest) {
  const res = NextResponse.next()
  const supabase = createMiddlewareClient({ req, res })
  const { error } = await supabase.auth.getSession()
  if (error) {
    // somehow handle the error
  }
  return res
}

I tried redirecting, rewriting, refreshing the session and logging the user out, but didn't have any success. It would be great if we could get an updated example in the docs that shows a way to handle this error gracefully.

rajat1saxena commented 1 year ago

I was simply away from my system for a while and my app was running in the dev mode. I was greeted with this error.

I am using the new @supabase/ssr package.

rodrigorm commented 12 months ago

I am not on an machine to test it now, but there is anywhere in supabase code deleting existing refresh token when use login on an different device?

alecmaire commented 12 months ago

Maybe I'm experiencing a different issue, but just want to throw my hat into this. A few weeks ago my app (which was working without issue up until then) suddenly started experiencing breaking issues, that I've traced back to constant token refreshes. Just loading the home page I see 10 requests for refresh tokens. Occasionally in my console it will print Invalid Refresh Token: Refresh Token Not Found. I've done a lot of digging into my userprovider hook (which is at the top level of my app) and it seems constant changes to the user variable and access token refreshes are causing my entire app to re render over and over. Again, maybe there's something I'm doing wrong somewhere, but the fact this bug arises out of nowhere with zero changes on my end makes me suspect it's some change with supabase

rodrigorm commented 12 months ago

Did you have any updates on your dependency which you point an specific version?

Em qua., 6 de dez. de 2023 às 16:42, alecmaire @.***> escreveu:

Maybe I'm experiencing a different issue, but just want to throw my hat into this. A few weeks ago my app (which was working without issue up until then) suddenly started experiencing breaking issues, that I've traced back to constant token refreshes. Just loading the home page I see 10 requests for refresh tokens. Occasionally in my console it will print Invalid Refresh Token: Refresh Token Not Found. I've done a lot of digging into my userprovider hook (which is at the top level of my app) and it seems constant changes to the user variable and access token refreshes are causing my entire app to re render over and over. Again, maybe there's something I'm doing wrong somewhere, but the fact this bug arises out of nowhere with zero changes on my end makes me suspect it's some change with supabase

— Reply to this email directly, view it on GitHub https://github.com/supabase/auth-helpers/issues/436#issuecomment-1843576946, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAFUHRAZGU3FFMXQYAEULTYIDDCDAVCNFSM6AAAAAAUGI4T2OVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNBTGU3TMOJUGY . You are receiving this because you commented.Message ID: @.***>

alecmaire commented 12 months ago

Nope. All of that was the same. I had started my app with this repo as a starting point and modified it for a new use case. Most of how the supabase auth etc works has remained the same. Perhaps maybe it has now become outdated? https://github.com/AntonioErdeljac/next13-spotify

astonfuture commented 11 months ago

I'm also getting this error specifically using a PWA on iOS. My app is also returning a 502 Bad Gateway when the error shows up

astonfuture commented 11 months ago

I'm also getting this error specifically using a PWA on iOS. My app is also returning a 502 Bad Gateway when the error shows up

I found a solution to the issue in my case. Remix has this behaviour where returning a redirect from a loader does not preserve the "Set-Cookie" headers from parent routes (whereas returning json does). So I was returning a redirect (without headers) and the refreshed auth tokens where therefore not being sent back to the client.

NickG-NZ commented 10 months ago

@silentworks

I just want to add some context to what's going on here because it is fundamentally not resolved. If you log in a user, then wait until the JWT expires (typically this happens if waiting overnight and come back the next day), the next call to getSession will throw this error: Invalid Refresh Token: Refresh Token Not Found. This is "expected" because the token has expired but the browser is still sending the cookie because you never logged out (and therefore never deleted the cookie).

Here's where the problem comes though: The way I would handle this (since the supabase team refuses to implement anything elegant), is to simply catch the error and delete the cookie. This seems easy enough but: Deleting the cookie requires you to know the name of the cookie, which is not possible unless you gave it a custom name.

Unfortunately giving the cookie a custom name (by passing cookieOptions tocreateServerClient) is broken (See my issue here: https://github.com/supabase/auth-helpers/issues/719 and may also be related to this issue: https://github.com/supabase/auth-helpers/issues/717

I don't know how anyone else is handling this, but it is a complete road-block for us.

ARMATAV commented 10 months ago

Yes this is an utter show stopper, similar to the previous time.

BorisBarzotto commented 10 months ago

How will this problem affect me in production? I need to get out with the application and I have not been able to turn this problem around.

NickG-NZ commented 10 months ago

The typical way your users will see this problem is if they login, leave for a while, come back later (on the same browser) after their token has expired and try access a protected route, triggering a call to getSession or getUser somewhere in your code. This returns an error (the one in the title of this issue) rather than simply a null session (which would indicate the user is not logged in, according to the docs).

Basically if a user doesn't log out at the end of their session (which I would consider the typical behavior of most users) you are likely to get this issue.

You may be able to "fix" this by catching the error from getSession and setting the "clear-site-data" cookie (See MDN Docs) in the headers of your response (assuming you are caling getSession on the server side). WARNING: this will clear all cookies for your app. The sensible solution would be to delete just the expired supabase cookie, unfortunately this is not currently possible in production because the cookie name is unknown (see my comment above and issue https://github.com/supabase/auth-helpers/issues/719)

Note this shouldn't be an issue if you are calling supabase from the browser. Renaming cookies can be done using the example in the docs here. And you can easily use the document.cookie = 'my-access-token='... after catching the error above. I haven't tested this since we don't touch supabase on the browser

jdgamble555 commented 10 months ago

@NickG-NZ - The problem is that it happens in a lot of non-typical circumstances, and there is also no way to "catch" the problem.

J

juliomuhlbauer commented 10 months ago

I think I will just move to next auth for now :(

chriscarrollsmith commented 10 months ago

I encountered this error during testing due to being logged in with a cookie from a user I deleted from my database. I seem to have fixed it with this workaround, which clears all Supabase-related cookies if this error is thrown:

import { type NextRequest } from 'next/server';
import { createClient } from '@/utils/supabase/middleware';

export async function middleware(request: NextRequest) {
  const { supabase, response } = createClient(request);
  const { error } = await supabase.auth.getSession();

  if (error?.message.match("Invalid Refresh Token")) {
    const allCookies = request.cookies.getAll();
    allCookies.forEach(cookie => {
      // Delete all Supabase cookies starting with 'sb-'
      if (cookie.name.startsWith('sb-')) {
        response.cookies.delete(cookie.name)
      }
    });
  }

  return response;
}
chriscarrollsmith commented 9 months ago

By the way, for reproducibility purposes, here's the context in which I encountered this error:

I have two separate Supabase projects that I test on the same 'http://localhost:3000". When I toggle between them, I often find myself logged in with cookies for the wrong project, and my middlewar throws this error.

JasonGross commented 9 months ago

Am I correctly understanding that the issue here is that supabase is handling refresh tokens behind the scenes in many cases, but when an expired session is still active,

  1. supabase does not gracefully handle this case, instead throwing an error; and
  2. supabase provides no way to handle this error, because it does not expose an API for interacting directly with the refresh tokens it uses?
NickG-NZ commented 9 months ago

You nailed it. Note also that the cookie names generated by the SSR package include a random hash. So even if you want to manipulate them manually you can't because you don't know the name.

My preference would be that supabase automatically deletes the expired cookie and returns a null session (indicating the user is not logged in).

Note that this problem can be resolved manually now that the issue with setting a custom cookie name has been fixed. (You can set your own name for the cookie by passing an option to "creatServerClient")

This means if this error occurs, you can just delete the cookie. And follow what ever your normal flow is for unauthenticated users.

Alternatively you can use the solution mentioned above and just remove all cookies starting with "sb-". This is the solution we initially implemented to get around the problem

ARMATAV commented 9 months ago

I do not see this behavior on a new nextjs project following exactly the steps in here and implementing the client side auth via this workaround so that you actually get the styling covered.

Seemingly, the token refresh behavior is taken care of. This is after around 1 day of letting the token expire etc.

Note that the Auth component is the one referenced in the above issue - pasting in my AuthButton so that other people can just try it out;

(obviously, you can delete those extraneous app/login components for this approach)

AuthButton.server.tsx

import React from "react";
import { createClient } from "@/utils/supabase/server";
import { cookies } from "next/headers";
import { AuthButtonClient } from "./AuthButton";

export const AuthButton = async () => {
  const cookieStore = cookies();
  const supabase = createClient(cookieStore);

  const {
    data: { user },
  } = await supabase.auth.getUser();

  return <AuthButtonClient initialUser={user} />;
};

AuthButton.tsx

"use client";

import { useEffect, useState } from "react";
import { Button } from "../ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "../ui/dialog";
import { Auth } from "./Auth";
import { createClient } from "@/utils/supabase/client";
import { User } from "@supabase/supabase-js";
import { Avatar, AvatarFallback, AvatarImage } from "../ui/avatar";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "../ui/dropdown-menu";
import { LogOut } from "lucide-react";

const supabaseClient = createClient();

type AuthButtonProps = {
  initialUser?: null | User;
};

export const AuthButtonClient = ({ initialUser }: AuthButtonProps) => {
  const [isDialogOpenState, setIsDialogOpenState] = useState<boolean>(false);
  const [userState, setUserState] = useState<undefined | User>(
    initialUser ?? undefined
  );

  const { auth } = supabaseClient;

  useEffect(() => {
    async function getUser() {
      const {
        data: { user },
      } = await auth.getUser();

      if (user) {
        setIsDialogOpenState(false);
        setUserState(user);
      }
    }

    getUser();
  }, [auth]);

  useEffect(() => {
    const { data: authListener } = auth.onAuthStateChange((event, session) => {
      if (event === "SIGNED_IN") {
        setIsDialogOpenState(false);
        setUserState(session?.user);
      }

      if (event === "SIGNED_OUT") {
        setUserState(undefined);
      }
    });

    return () => {
      authListener?.subscription.unsubscribe();
    };
  }, [auth]);

  const handleLogOutClicked = () => {
    auth.signOut();
    setUserState(undefined);
  };

  const { email, user_metadata } = userState ?? {};
  const { avatar_url } = user_metadata ?? {};

  return (
    <>
      <Dialog open={isDialogOpenState} onOpenChange={setIsDialogOpenState}>
        <DialogContent className="sm:max-w-[425px]">
          <DialogHeader>
            <DialogTitle>Sign in</DialogTitle>
            <DialogDescription>to continue to Skipit</DialogDescription>
          </DialogHeader>

          <div className="">
            <Auth />
          </div>
        </DialogContent>
      </Dialog>

      {userState && (
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Avatar>
              <AvatarImage src={avatar_url} alt="user avatar" />
              <AvatarFallback className="select-none">
                {email ? email[0].toUpperCase() : ""}
              </AvatarFallback>
            </Avatar>
          </DropdownMenuTrigger>
          <DropdownMenuContent className="w-56">
            <DropdownMenuLabel>My Account</DropdownMenuLabel>
            <DropdownMenuSeparator />
            <DropdownMenuItem onClick={handleLogOutClicked}>
              <LogOut className="mr-2 h-4 w-4" />
              <span>Log out</span>
            </DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
      )}
      {!userState && (
        <div>
          <Button
            onClick={() => {
              setIsDialogOpenState(true);
            }}
          >
            Sign In
          </Button>
        </div>
      )}
    </>
  );
};

middleware.ts

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

export async function middleware(request: NextRequest) {
  let response = NextResponse.next({
    request: {
      headers: request.headers,
    },
  });

  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        get(name: string) {
          return request.cookies.get(name)?.value;
        },
        set(name: string, value: string, options: CookieOptions) {
          request.cookies.set({
            name,
            value,
            ...options,
          });
          response = NextResponse.next({
            request: {
              headers: request.headers,
            },
          });
          response.cookies.set({
            name,
            value,
            ...options,
          });
        },
        remove(name: string, options: CookieOptions) {
          request.cookies.set({
            name,
            value: "",
            ...options,
          });
          response = NextResponse.next({
            request: {
              headers: request.headers,
            },
          });
          response.cookies.set({
            name,
            value: "",
            ...options,
          });
        },
      },
    }
  );

  await supabase.auth.getUser();

  return response;
}

export const config = {
  matcher: [
    /*
     * Match all request paths except for the ones starting with:
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - favicon.ico (favicon file)
     * Feel free to modify this pattern to include more paths.
     */
    "/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",
  ],
};

This is with everything at their latest versions on a fresh project using shadcdn for the other components.

Again it seems all good, even after multiple expirations take place, it seems to refresh properly.

ummahusla commented 9 months ago

Ugh, and still no good solution to this problem? Because I tried everything I found in github issues, reddit and there is still no valid workaround it seems.

mbeaudru commented 9 months ago

From what I've found, it seems that the refresh token workflow works well until supabase/ssr decides to split the cookie in two chunks. Maybe the refresh token code misses to handle this situation.

In my case, the refresh token workflow works well with email login, but it doesn't work properly with google signin/up as it pulls all user info in cookies and it gets split.

I didn't found time to investigate this further and submit a PR yet, so take it with a grain of salt. In the meantime, going back to old auth-helpers package helps, but this would be really awesome for the refresh token workflow to work again reliably with supabase/ssr - because as of today users are forced-unlogged as soon as the JWT token expires (1h by default)

CarlosBalladares commented 8 months ago

This happens when i have an old token, calling getUser() doesn't overwrite the old token unless i sign in again. Any ideas on workarounds?

aplyd commented 8 months ago

commenting because I'm also experiencing this issue with social logins (azure specifically). the user being logged out every hour isn't a huge issue in my scenario but definitely inconvenient.

singuerinc commented 8 months ago

Hi folks, any update on this? I keep getting 404 on the site I'm building if I don't visit it for a few hours. This is terrible for business critical apps and users who won't bother in refreshing the page (which I assume are all). I'm seriously thinking about migrating away if this is not resolved (which is also frustrating giving all the hours I invested in making it work with Supabase).

hf commented 8 months ago

From what I've found, it seems that the refresh token workflow works well until supabase/ssr decides to split the cookie in two chunks. Maybe the refresh token code misses to handle this situation.

In my case, the refresh token workflow works well with email login, but it doesn't work properly with google signin/up as it pulls all user info in cookies and it gets split.

I didn't found time to investigate this further and submit a PR yet, so take it with a grain of salt. In the meantime, going back to old auth-helpers package helps, but this would be really awesome for the refresh token workflow to work again reliably with supabase/ssr - because as of today users are forced-unlogged as soon as the JWT token expires (1h by default)

OK thanks for this insight. I'll check the code there.

hf commented 7 months ago

These are some fixes I identified that could be causing weird issues: https://github.com/supabase/auth-helpers/pull/760

hf commented 7 months ago

Also one thing that may be confusing you is if you are getting this error on localhost, not on production. This is somewhat expected on localhost because the cookies remain in place forever, but your backend / database is not there. So it's normal to get Invalid Refresh Token errors if your database has changed.

How many of you are actually seeing this on a real, live project (or staging environment) -- not local development?

mbeaudru commented 7 months ago

Thanks for starting investigations, really appreciated!

I moved on to something else so I won't be able to give more valuable feedback moving forward, but I have to say that I had invalid refresh token happening on prod on my end sadly, not just localhost

hf commented 7 months ago

OK I've done a deep dive into this with NextJS. It is very important for your middleware.ts file to look exactly like this to prevent this from happening.

If it's just a bit off, your server-rendered pages and components won't see the correct state and all hell will break loose.

https://supabase.com/docs/guides/auth/server-side/creating-a-client?environment=middleware

astonfuture commented 7 months ago

Also one thing that may be confusing you is if you are getting this error on localhost, not on production. This is somewhat expected on localhost because the cookies remain in place forever, but your backend / database is not there. So it's normal to get Invalid Refresh Token errors if your database has changed.

How many of you are actually seeing this on a real, live project (or staging environment) -- not local development?

I'm seeing this is production with Remix but interestingly I haven't been able to reproduce on localhost

hawkcookie commented 7 months ago

@hf Thanks you for the investigation! I am also seeing this issue in production with Remix deployed to cloudflare pages. A log is below. This event occurs only rarely, but a few users have encountered this issue.

Log Event Message

{"component":"api","error":"invalid_grant: Invalid Refresh Token: Refresh Token Not Found","level":"info","method":"POST","msg":"invalid_grant: Invalid Refresh Token: Refresh Token Not Found","path":"/token","referer":"XXXXXXX","remote_addr":"2a06:98c0:3600::103","time":"2024-04-05T14:38:33Z","timestamp":"2024-04-05T14:38:33Z"}
Log Meta Data
[
  {
    "message": null,
    "timestamp": "2024-04-05T14:38:33Z",
    "__MONOTONIC_TIMESTAMP": null,
    "CODE_FUNC": null,
    "instance_id": null,
    "status": null,
    "_CMDLINE": null,
    "method": "POST",
    "_SYSTEMD_CGROUP": null,
    "CODE_FILE": null,
    "EXECUTABLE": null,
    "_EXE": null,
    "UNIT": null,
    "level": "info",
    "_COMM": null,
    "duration": null,
    "issuer": null,
    "_LINE_BREAK": null,
    "_SOURCE_REALTIME_TIMESTAMP": null,
    "msg": "invalid_grant: Invalid Refresh Token: Refresh Token Not Found",
    "action": null,
    "login_method": null,
    "_UID": null,
    "host": "XXXXXXXX,
    "PRIORITY": null,
    "_CAP_EFFECTIVE": null,
    "_PID": null,
    "INVOCATION_ID": null,
    "_SYSTEMD_UNIT": null,
    "source_type": null,
    "SYSLOG_FACILITY": null,
    "request_id": null,
    "CODE_LINE": null,
    "path": "/token",
    "component": "api",
    "project": null,
    "user_id": null,
    "auth_event": [],
    "args": [],
    "referer": "XXXXXXX",
    "factor_id": null,
    "provider": null,
    "client_id": null,
    "remote_addr": "2a06:98c0:3600::103",
    "_SYSTEMD_SLICE": null,
    "_SYSTEMD_INVOCATION_ID": null,
    "header": null,
    "_MACHINE_ID": null,
    "_AUDIT_LOGINUID": null,
    "_TRANSPORT": null,
    "_SELINUX_CONTEXT": null,
    "MESSAGE_ID": null,
    "__REALTIME_TIMESTAMP": null,
    "metadata": [],
    "_STREAM_ID": null,
    "metering": null,
    "time": null,
    "_GID": null,
    "_BOOT_ID": null,
    "SYSLOG_IDENTIFIER": null,
    "_AUDIT_SESSION": null,
    "error": "invalid_grant: Invalid Refresh Token: Refresh Token Not Found"
  }
]
singuerinc commented 7 months ago

Also one thing that may be confusing you is if you are getting this error on localhost, not on production. This is somewhat expected on localhost because the cookies remain in place forever, but your backend / database is not there. So it's normal to get Invalid Refresh Token errors if your database has changed.

How many of you are actually seeing this on a real, live project (or staging environment) -- not local development?

I can reproduce it in production always. I just need to wait less than a day, I check the production site and it always fails on the first load.

singuerinc commented 7 months ago

OK I've done a deep dive into this with NextJS. It is very important for your middleware.ts file to look exactly like this to prevent this from happening.

If it's just a bit off, your server-rendered pages and components won't see the correct state and all hell will break loose.

supabase.com/docs/guides/auth/server-side/creating-a-client?environment=middleware

I understand that this is ideal, but in a real application the middleware could look different.

In my case I have next-intl configured:

next-intl modifies the middleware https://next-intl-docs.vercel.app/docs/getting-started/app-router#middleware

So for example, I need to modify the matcher, which it may create some problems?

cervantes-x commented 7 months ago

Any updates on this? Our users get signed out at random times because of this and it's a big issue for our app.

singuerinc commented 7 months ago

@cervantes-x I found out they changed the docs few months ago with a suspicious change:

https://github.com/supabase/supabase/commit/94a07fe7245ba0c3c4a796e270c54131b1b40d4e#diff-dd339bd5166457f97527bb5dd3507aa30e4c4d12a336b527e6baeb84d6a978c2R225

I had in my middleware:

await supabase.auth.getSession();

but in the docs now says:

await supabase.auth.getUser();

I haven't tested it yet, but any application created prior to that change (4 months ago) I guess should update to that.

I'll monitor my app for a while and post some update.

harrisrobin commented 7 months ago

@cervantes-x I found out they changed the docs few months ago with a suspicious change:

https://github.com/supabase/supabase/commit/94a07fe7245ba0c3c4a796e270c54131b1b40d4e#diff-dd339bd5166457f97527bb5dd3507aa30e4c4d12a336b527e6baeb84d6a978c2R225

I had in my middleware:

await supabase.auth.getSession();

but in the docs now says:

await supabase.auth.getUser();

I haven't tested it yet, but any application created prior to that change (4 months ago) I guess should update to that.

I'll monitor my app for a while and post some update.

This seems to have helped, however every user that's visited the site since this change has had to manually clear their cookies, otherwise they were permanently met with a 500, so be careful before making that change in a production system without handling the error.

Once sb- cookies are cleared, things are pretty smooth so far.

hawkcookie commented 7 months ago

@cervantes-x I found out they changed the docs few months ago with a suspicious change:

https://github.com/supabase/supabase/commit/94a07fe7245ba0c3c4a796e270c54131b1b40d4e#diff-dd339bd5166457f97527bb5dd3507aa30e4c4d12a336b527e6baeb84d6a978c2R225

I had in my middleware:

await supabase.auth.getSession();

but in the docs now says:

await supabase.auth.getUser();

I haven't tested it yet, but any application created prior to that change (4 months ago) I guess should update to that.

I'll monitor my app for a while and post some update.

It sounds like you're suspecting that the issue might not be resolved because the getUser method is calling the same getSession method(https://github.com/supabase/auth-js/blob/bd91e72824ceb075f6fca7ae25bf9f066e6508d2/src/GoTrueClient.ts#L1195-L1207). In fact, in my application, I'm experiencing Invalid Refresh Token: Refresh Token Not Found randomly when using getUser.

singuerinc commented 6 months ago

ok, it didn't solve the issue. I'm tired of this and no support from Supabase.

tomekit commented 6 months ago

You might consider commenting here: https://github.com/orgs/supabase/discussions/26864 to provide an option for Supabase to disable Refresh Token invalidation, as is the case with e.g. Firebase (https://firebase.google.com/docs/auth/admin/manage-sessions)

Whilst it won't solve all: "Refresh Token" issues that users are reporting here, it will address some of them, especially related to race conditions or other failures whilst requesting or/and persisting new accessToken.

ElectricCodeGuy commented 6 months ago

Can't believe this is still an issue, some of my costumers have also raised tickets on exactly this. I thought it was fixed month ago but yet here we are... How is this so hard to fix? When the users session/auth cookie is timed out and they try and access the site an error is unhandled resulting in an error 500 black screen... This is coming from the Middleware. Anyone have a solution to this? Been like this for about 1 year now.... Users are also getting signed out at random interval like other have reported...

j4w8n commented 6 months ago

I'm guessing that https://github.com/supabase/auth-helpers/pull/780 is hoping to resolve a lot of this. No movement on it since creation though. However, I may be misunderstanding it's relevance to this issue.

hf commented 5 months ago

Please refer to this discussion to see what we're doing about issues like this: https://github.com/orgs/supabase/discussions/27037

Link to PR that addresses all of these issues: https://github.com/supabase/ssr/pull/1

daveycodez commented 5 months ago

Not sure if this is a new bug that was introduced. I have a nearly identical code base to my cloned project and I am using Pages router.

Original working versions that don't log me out after weeks of inactivity on my old site:

    "@supabase/auth-helpers-react": "^0.4.2",
    "@supabase/auth-ui-react": "^0.4.2",
    "@supabase/auth-ui-shared": "^0.1.6",
    "@supabase/postgrest-js": "^1.9.2",
    "@supabase/ssr": "^0.0.10",
    "@supabase/supabase-js": "^2.23.0",

Broken website has these versions:

    "@supabase/auth-helpers-react": "^0.4.2",
    "@supabase/auth-ui-react": "^0.4.7",
    "@supabase/auth-ui-shared": "^0.1.8",
    "@supabase/postgrest-js": "^1.15.5",
    "@supabase/ssr": "^0.0.10",
    "@supabase/supabase-js": "^2.43.5",

Do I just downgrade to old Supabase? Feels bad... Thought we were production ready. I get signed out every morning I wake up.

{"component":"api","error":"invalid_grant: Invalid Refresh Token: Refresh Token Not Found","level":"info","method":"POST","msg":"invalid_grant: Invalid Refresh Token: Refresh Token Not Found","path":"/token","referer":"https://aquarion.ai/","remote_addr":"73.66.181.162","request_id":"896609dca6e632b9-SMF","time":"2024-06-19T19:48:46Z"}

Glognus commented 4 months ago

I have the same issue on a react native app

rusakovic commented 3 months ago

Confirm the issue

agallio commented 3 months ago

It's also happening on my React Native / React SPA production apps. And it seems like the error is coming from the supabase library directly and can't be intercepted (adding error logging to sentry for example). So I can't figure out what exactly the root cause is.

k2xl commented 2 months ago

I am experiencing this occasionally. What are some workarounds?