auth-helpers icon indicating copy to clipboard operation
auth-helpers copied to clipboard

Invalid Refresh Token: Refresh Token Not Found

Open bukinoshita opened this issue 2 years ago • 101 comments

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

  • OS: [e.g. macOS, Windows]
  • Browser (if applies) [e.g. chrome, safari]
  • Version of supabase-js: [e.g. 6.0.2]
  • Version of Node.js: [e.g. 10.10.0]

Additional context

Add any other context about the problem here.

bukinoshita avatar Jan 25 '23 12:01 bukinoshita

One of the places I found this error is when calling getSession, it sees the session as expired, then calls the gotrue api to try and refresh the session. Part of that process is trying to find a user that has the refresh token. If something goes wrong when searching for a user, it'll return this error.

Can you look in your auth.refresh_tokens table and find an entry that matches the token?

j4w8n avatar Jan 26 '23 21:01 j4w8n

One of the places I found this error is when calling getSession, it sees the session as expired, then calls the gotrue api to try and refresh the session. Part of that process is trying to find a user that has the refresh token. If something goes wrong when searching for a user, it'll return this error.

Yeah, that exactly the call that it's giving me that error.

Can you look in your auth.refresh_tokens table and find an entry that matches the token?

What should I look here? Whenever I get the error, I try to find a refresh token that matches the current token?

Btw, a temporary "solution" was to increase the user session from 1 hour to 1 week, so it minimize the error occurrence.

bukinoshita avatar Jan 27 '23 07:01 bukinoshita

What should I look here? Whenever I get the error, I try to find a refresh token that matches the current token?

Yes

What's the timeframe between when a user signs in and when this error occurs?

j4w8n avatar Jan 27 '23 10:01 j4w8n

Need to investigate, the application is production — what would be the best way to track this? Should I change the session time to 1 hour again and see if the error happens with more frequency?

bukinoshita avatar Jan 27 '23 22:01 bukinoshita

You could try increasing the reuse interval. The client and server might be refreshing fairly close to each other in with that invalidate the token. But yah, if you have a log drain would also be good to see what's happening within the middleware function.

image

thorwebdev avatar Jan 30 '23 07:01 thorwebdev

Did you ever solve this issue? Im running into the same problem

yairhaimo avatar Mar 24 '23 21:03 yairhaimo

Not sure why, but this happened on my local dev server, and when I restarted, the problem was gone.

J

jdgamble555 avatar May 01 '23 02:05 jdgamble555

I am trying to refresh user data by calling auth.getUser() and am facing the same error.

dsebastien avatar May 31 '23 12:05 dsebastien

+1 for this issue! I'm having it in the dart client ever since I cloned the user_management_example project and have to sign in using the magic link every time.

nathantaal avatar Jul 10 '23 13:07 nathantaal

Did you ever solve this issue? Im running into the same problem

Increasing the interval "solved" the issue. I don't think this is the ideal solution, but for me it stopped breaking the application at least.

bukinoshita avatar Jul 11 '23 15:07 bukinoshita

Did you ever solve this issue? Im running into the same problem

Increasing the interval "solved" the issue. I don't think this is the ideal solution, but for me it stopped breaking the application at least.

What did you increase this to?

I'm also running into this issue with auth.getSession() when using createRouteHandlerClient from @supabase/auth-helpers-nextjs

RyanCarterTheDev avatar Jul 14 '23 16:07 RyanCarterTheDev

If I recall correctly the workaround was to increase this to the max CleanShot 2023-07-18 at 17 22 23@2x

bukinoshita avatar Jul 18 '23 20:07 bukinoshita

But is this also a solution, or will it only make the issue very less like to happen? So in the example of this max seconds being a week, will will get the error again if we logon to the app only to open it 8 days later..?

nathantaal avatar Jul 23 '23 10:07 nathantaal

Also experiencing this

MilesV64 avatar Jul 31 '23 23:07 MilesV64

Ok, I have a reproducible Scenario where this happens on my server. If I load balance to multiple instance and when user logs in on browser to use my service, the load balanced instance can get changed and user's frontend server can be redirected to a different server than the one he or she logged in. Since the Next js app in a new instance does not have a refresh token for the cookie that it is getting, it returns "Refresh Token Not Found". This is fine if I can log the user out.

I can't seem to log the user out in a proper way, maybe like the signOut api await supabase.auth.signOut, since this also throws the token not found error...

I guess I have to automatically clear cookies of users every time I encounter this?

Please let me know if I'm wrong here. I need help.

EDIT: not really sure it is because of multiple instances at this moment. might just be other bug.

seho0808 avatar Aug 04 '23 10:08 seho0808

@david-plugge is this similar to https://github.com/supabase/auth-helpers/issues/343 ?

swyxio avatar Aug 05 '23 01:08 swyxio

Now getting same problem. Not quite sure what triggered it in the first place as it was working ok until now. It might be that I logged out the user and since I logged back in, it started giving this error.

Increasing JWT expiry (to several values and up to maximum) and increasing reuse interval in settings/auth did not solve it for me.

This is all with local development in NextJS 13, logging in with Google OneTap.

titocosta avatar Aug 11 '23 13:08 titocosta

We haven't been able to reproduce this issue and will find it hard to fix since we have no way of seeing or testing the issue. Can one of you on the thread provide a reproducible repository with the issue so we can take a look at it.

silentworks avatar Aug 15 '23 20:08 silentworks

@silentworks - One of the ways this has been triggered is by logging in to my website, then running supabase db reset (or stop and start). Since I'm still logged in, and the database is empty, it will result in this error. I believe logging out first before resetting the database fixes this problem, and probably what is expected.

There are other cases, and as I find them (may be randomly in the future), I will post a repo and try and replicate it.

I can't speak for anyone else.

J

jdgamble555 avatar Aug 15 '23 22:08 jdgamble555

@silentworks for me is at easy as checking out the Flutter user management example, logon once, waiting 24 hours and opening the app once again. The wait time is important here.

nathantaal avatar Aug 16 '23 17:08 nathantaal

We haven't been able to reproduce this issue and will find it hard to fix since we have no way of seeing or testing the issue. Can one of you on the thread provide a reproducible repository with the issue so we can take a look at it.

I think I found a reproducible one which produces a similar result. Could you please try this scenario?

  1. set JWT expiry limit to lowest as possible (which is 1200 currently)
  2. login to supabase auth based app
  3. in developer console, get the document.cookie for our JWT token. keep this somewhere else.
  4. logout of supabase auth based app we logged in from step2.
  5. wait for expiry time. (1200 seconds in this case)
  6. on a fresh app website page that isn't logged in, inject the document.cookie from step3.
  7. refresh so that document.cookie takes effect.
  8. You get bunch of errors on server and client. Below statement prints multiple times in my server for next.js app.
[AuthApiError: Invalid Refresh Token: Refresh Token Not Found] {
1|vhub_fe  |   __isAuthError: true,
1|vhub_fe  |   name: 'AuthApiError',
1|vhub_fe  |   status: 400
1|vhub_fe  | }
  1. The problem here is that none of supabase-js api works so I can't even await supabase.signOut().

Disclaimer here is that my bug happens to have same result, but I never log out of the app nor do I turn off my server. My server is always online, and "Refresh token not found" happens after some time has passed. Also not sure what the expiry was set in cookie for the actual error scenario, but in actual scenario, the error persisted even if I closed the browser and reentered the website.

My current solution to bypass Refresh Token Not Found in production - this simply logs out the user: (part of middleware.ts)

const res = NextResponse.next();
const supabase = createMiddlewareClient<Database>({ req, res });
const {
  data: { session },
  error,
} = await supabase.auth.getSession();

if (error) {
  res.cookies.delete("my-auth-token-name");
  return ["error", res];
}

seho0808 avatar Aug 17 '23 14:08 seho0808

@seho0808 Thank you for providing the solution. I'm facing the same issue.

acomanescu avatar Aug 18 '23 14:08 acomanescu

@seho0808 those steps don't make sense as that is intentionally creating an issue. The auth-helpers does auto-refreshing of the token so you logging out would remove the whole effect of the auto-refreshing happening. Please provide an example app repository simulating this issue whilst logged in. Intentionally breaking the flow to create an issue isn't a good way to fix an issue.

silentworks avatar Aug 21 '23 10:08 silentworks

@seho0808 those steps don't make sense as that is intentionally creating an issue. The auth-helpers does auto-refreshing of the token so you logging out would remove the whole effect of the auto-refreshing happening. Please provide an example app repository simulating this issue whilst logged in. Intentionally breaking the flow to create an issue isn't a good way to fix an issue.

I apologize for a bad example. I couldn't find a way to reproduce it so I shared a closest example to what I can simulate. I will try not to provide such examples from now on. Thank you for the reply!

seho0808 avatar Aug 21 '23 11:08 seho0808

I believe the issue is that you have info in your cookies that references a deleted user.

wdavidturner avatar Aug 25 '23 04:08 wdavidturner

the issue is still there. Any solution or workaround?

@wdavidturner I have the same issue, it happens when the auth token expires but the user is still logged in.

louishugens avatar Aug 25 '23 15:08 louishugens

I have the same error, I deleted user in auth tab while beeing login on my localhost, clearing cookies do nothing

wojtekKrol avatar Aug 27 '23 16:08 wojtekKrol

@wojtekKrol I just tested this and my user gets logged out (which is what should happen) when the token tried refreshing along with the error from the API (which should be handled by yourself in your code). My test project can be found here if you'd like to inspect the code https://github.com/supabase-community/supabase-by-example/tree/main/reset-flow/nextjs.

silentworks avatar Sep 11 '23 15:09 silentworks

I've just re-read all the messages here and now I'm wondering what the actual issue is? All the scenarios provided seem to lead to the same error but the developer should be handling the error in their app. This isn't something that supabase-js or auth-helpers should manage as this is down to error management in your app itself. Please reply to this message with what you expect to happen when your token has expired and not able to refresh due to whatever reason.

silentworks avatar Sep 11 '23 16:09 silentworks

I've just re-read all the messages here and now I'm wondering what the actual issue is? All the scenarios provided seem to lead to the same error but the developer should be handling the error in their app. This isn't something that supabase-js or auth-helpers should manage as this is down to error management in your app itself. Please reply to this message with what you expect to happen when your token has expired and not able to refresh due to whatever reason.

I started my project based upon the supabase sveletekit auth example and I'm running into this same thing. Are you thinking that the example code needs to be updated to solve this issue?

jareddr avatar Sep 17 '23 14:09 jareddr