Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unknown or invalid refresh token #498

Closed
adikari opened this issue Sep 15, 2021 · 22 comments
Closed

Unknown or invalid refresh token #498

adikari opened this issue Sep 15, 2021 · 22 comments
Labels
question Further information is requested

Comments

@adikari
Copy link

adikari commented Sep 15, 2021

Description

I am using nextjs auth0 in api routes and also protecting some pages on the client side using the hoc. I also have a API proxy to my graphql server where I call getAccessToken to add Authorization header. The graphql proxy API is protected with withAPIAuthRequired.

Both my client side protected pages and the api routes are working as expected. I am running into a weird scenario where I seem to have an active session as the protected pages and api routes are still accessible. However, when the getAccessToken is invoked I am receiving Unknown or invalid refresh token error from Auth0.

I am currently configuring the sdk using environment variables. I also pass the offline_access scope along with other required ones using the environment variable. In auth0 configuration I have refresh token rotation enabled. I have verified the refresh tokens are working by setting the token expiry to about 1 minute then checking the logs in auth0. I can confirm that I can see the token getting refreshed via the log.

However, in some scenarios (I am not sure how this gets triggered), I am receiving the specified error when I call the getAccessToken which fails to renew the refresh token. If I redirect user to the login page then the token is refreshed. I am under impression that the getAccessToken would automatically refresh token and I do not need to perform this step.

I am not entirely sure if I am missing some configuration in the SDK or not. Upon browsing through similar issues from the past, I noticed there is an option to storeRefreshToken. I am suspecting it could be related to it but not entirely sure. I went ahead and checked the source code for configuration and I do not see any option for this.

I have also checked the example repository which is using initAuth0 which uses some extra session configuration that I am not currently using.

Also, even though I am getting the invalid refresh token error, my auth0 session seem to still be valid and the user is still logged in. What should happen in this scenario? Should the user be logged out automatically or is this something I will need to handle in the application?

I would appreciate any help in solving this issue.

@Widcket
Copy link
Contributor

Widcket commented Sep 17, 2021

Hi @adikari, thanks for raising this.

I am not entirely sure if I am missing some configuration in the SDK or not. Upon browsing through similar issues from the past, I noticed there is an option to storeRefreshToken. I am suspecting it could be related to it but not entirely sure. I went ahead and checked the source code for configuration and I do not see any option for this.

The storeRefreshToken option was removed on v1.0.0:
Screen Shot 2021-09-17 at 00 16 15

Are you using initAuth0? If so, you need to make sure to always use that custom instance instead of the default instance created by the SDK.

@Widcket Widcket added the question Further information is requested label Sep 17, 2021
@adikari
Copy link
Author

adikari commented Sep 17, 2021

@Widcket i am not using initAuth0. I am configuring the client via environment variables. I can confirm the refresh tokens works sometimes as I can see it in the auth0 logs. It's usually after about 12 hours that I get this error.

The other thing I can think of is, currently I am using this only on the api and don't plan to use this in the client. Hence I am not wrapping my app with the auth0 provider. I am not sure it that will make any difference. In surface it does not look like it will as everything but this is working as expected.

@Widcket
Copy link
Contributor

Widcket commented Sep 17, 2021

@adikari see #333 (comment). What is your Refresh Token inactivity lifetime? If it's too short you will run into issues.

@adikari
Copy link
Author

adikari commented Sep 17, 2021

@Widcket It is a fairly large value so I don't think it's the same issue. Attached is the screenshot with the configuration

image

@Widcket
Copy link
Contributor

Widcket commented Sep 23, 2021

@adikari, are you revoking the refresh token?

One important detail is that when you revoke a token, for security reasons the grants associated with that token are deleted. This means that all other refresh tokens issued to the same combination of application, user and audience effectively become invalid. If you are revoking refresh tokens as part of your flow, this might explain it.

See https://community.auth0.com/t/invalid-refresh-token/10335

@adikari
Copy link
Author

adikari commented Sep 23, 2021

I am not really doing anything fancy here. Just using the library as it is with the recommended settings and configuration. Recently I have not seen the error on production and is only happening in local host.

@karlisl
Copy link

karlisl commented Sep 23, 2021

We noticed the same behavior today, some sessions with supposedly valid refresh token expiry dates started throwing this error. Last login performed 10 days ago, last successful token exchange 12 hours ago when it started failing. Absolute refresh token lifetime set to 30 days (2592000), inactivity to 15 days (1296000).

@adamjmcgrath
Copy link
Contributor

Hi @adikari - have you set your Auth0 application up as a "Single Page App" or a "Regular Web Application"? It should be a "Regular Web Application"

I see you have Refresh Token Rotation (RTR) enabled, which is fine, but for Regular Web Applications we default this to off (we only recommend RTR for public clients like mobiles or SPAs)

Your intermittent failed RT exchanges could be caused by Rotated Tokens being reused and triggering breach detection (You can search for "ferrt" errors in your tenant logs to confirm)

If it's not that, we can investigate if you share your client id and tenant domain.

@adikari
Copy link
Author

adikari commented Sep 24, 2021

@adamjmcgrath interestingly I have not seen any errors for about a week now. The application is set to be SPA. I did update my nextjs app and wrapped the app component with the Provider eventhough I am not using the useUser hook. I am not sure if this is related.
My use case is, all my pages require login so all pages are wrapped with withPageAuthRequired and I use the user loaded in the backend to pass down to components as a prop. I don't really need to use the useUser hook except in the profile page so thinking of just wrapping that component with the Provider.
I will make a change tonight and remove the Provider tonight and observe for couple of days to see if the issue comes back. I will also go through the auth0 logs and search for the keyword you recommended to confirm if it was that issue.

I observed that if I wrap my app with the Provider, for every page changes it performs a call to /me endpoint even though the user would have already been loaded in the server by withPageAuthRequired. Is this the expected behaviour? If yes would be good to understand why we do the call to load the user eventhough the client is not using the useUser hook.

Thank you

@adikari
Copy link
Author

adikari commented Sep 24, 2021

Also a general question about the usage of the sdk. In case of the invalid token error, user session is still valid so they are logged in to the client. However, because of the invalid token, all my graphql queries would fail. Should the sdk invalidate the session and force the user to login again in such scenario? Is there a recommended way to invalidate the user session? This leaves the client in a weird spot where the user is logged in but none of the api endpoints would work.

@adikari
Copy link
Author

adikari commented Sep 24, 2021

@adamjmcgrath As you suggested, it seems like it's the token reuse detection invalidating the request token. Looking at the logs seems like there are multiple requests being made to get the refresh token. The first one failed then there was another one that was successfully made then another one failed which would have probably invalidated the successfully refreshed token?

image

@adamjmcgrath
Copy link
Contributor

The application is set to be SPA.

The application should be set to "Regular Web Application"

@adamjmcgrath As you suggested, it seems like it's the token reuse detection invalidating the request token.

You should set your application to "Regular Web Application" and disable Refresh Token Rotation. Then you wont get issues with reuse detection.

If you really want to have Rotating Refresh Token's you may have to live with intermittent reuse errors (You can increase the "Reuse interval" to reduce the chance of these happening)

@adikari
Copy link
Author

adikari commented Sep 28, 2021

@adamjmcgrath i have made the necessary changes and will monitor for a bit. But that still does not explain what or how my refresh tokens are invalidated. Wouldn't it be more secure to use the token rotation?

@adamjmcgrath
Copy link
Contributor

But that still does not explain what or how my refresh tokens are invalidated

Concurrent requests can trigger the reuse detection. Imagine a request for a new Access Token is issued and before it responds with a rotated Refresh Token another request is issued using the same Refresh Token, the first request will succeed and rotate the Refresh Token so the second request will fail because it will be using a Refresh Token that’s already been used.

Wouldn't it be more secure to use the token rotation?

Potentially yes - but there is a trade of with reliability and reuse detection, which is why we tend to default to non rotated for confidential clients

Closing this, feel free to ping me to reopen if you're still seeing issues

@adikari
Copy link
Author

adikari commented Sep 28, 2021

Thank you for helping out. I will monitor it for few days and ping you if I have further issues.

@Alarid
Copy link

Alarid commented Dec 2, 2022

@adikari Did you find the solution? I'm having the same issue, and I find it really hard to understand. NextJS app configured as a Regular Web App, token rotation disabled, offline_access specified in the scope, refresh token enabled, pretty much the same configuration as you. When I log in, I usually start seeing the issue after a few days: when I request the access token with getAccessToken(req, res), I get the error "Unknown or invalid refresh token.".

If I try to get another refresh token using either the node-auth sdk with auth0Client.refreshToken({refreshToken: session.refresh_token}), I get the same error. I've been reading the docs for days, and I still can't find a solution to this. Any help appreciated

@adikari
Copy link
Author

adikari commented Dec 2, 2022

@Alarid start from here. It might help #498 (comment)

@Alarid
Copy link

Alarid commented Dec 2, 2022

@Alarid start from here. It might help #498 (comment)

Thanks for your quick reply! I disabled token rotation, I will see if it solves the issue. So, just to be sure: there's nothing in particular I need to do to refresh this "refresh token" with this setting disabled?

@adikari
Copy link
Author

adikari commented Dec 2, 2022

I haven't used the library for a while now but from memory when you get the access token using the SDK it will automatically refresh the token if the token has expired.

@Alarid
Copy link

Alarid commented Dec 6, 2022

It seems to be the case yes, thanks again @adikari

@javagovindsharma
Copy link

@adikari I am getting an invalid access token, in my Auth0 application have applied RS256 signature format.
for validation, I used the JWT.io port but I found a blank head and payload,

@punksta
Copy link

punksta commented Apr 27, 2024

Hi Guys,

Update created an issue:

#1739

We are experiencing a similar problem.

We use Next.js on Vercel.
Refresh token rotation is disabled.
The application type is set to a Regular Web App

Login/logout works, but we are getting many invalid refresh token errors.

Screenshot 2024-04-27 at 12 58 32

Auth0 error event:

{
  "date": "2024-04-27T10:56:28.619Z",
  "type": "fertft",
  "description": "Unknown or invalid refresh token.",
  "connection_id": "",
  "client_id": "XXX",
  "client_name": "XXX",
  "ip": "XXX",
  "user_agent": "Other 0.0.0 / Other 0.0.0",
  "hostname": "XXX.auth0.com",
  "user_id": "",
  "user_name": "",
  "auth0_client": {
    "name": "nextjs-auth0",
    "version": "3.5.0",
    "env": {
      "node": "v18.20.0"
    }
  },
  "$event_schema": {
    "version": "1.0.0"
  },
  "log_id": "90020240427105628747791000000000000001223372040511347164",
  "_id": "90020240427105628747791000000000000001223372040511347164",
  "isMobile": false,
  "id": "90020240427105628747791000000000000001223372040511347164"
}

Vercel error log:

i [AccessTokenError]: The request to refresh the access token failed. CAUSE: invalid_grant (Unknown or invalid refresh token.)
    at h.refresh (/var/task/.next/server/chunks/9355.js:1:4131)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    ... 7 lines matching cause stack trace ...
    at async Y (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:16:24556) {
  code: 'ERR_FAILED_REFRESH_GRANT',
  cause: o [Error]: invalid_grant (Unknown or invalid refresh token.)
      at h.refresh (/var/task/.next/server/chunks/9355.js:1:4248)
      at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
      at async Object.getAccessToken (/var/task/.next/server/chunks/9355.js:1:56971)
      at async m (/var/task/.next/server/chunks/2144.js:17:2133)
      at async n (/var/task/.next/server/app/api/billing/verify/route.js:17:2335)
      at async p (/var/task/.next/server/app/api/billing/verify/route.js:1:1455)
      at async /var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:42484
      at async eI.execute (/var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:32486)
      at async eI.handle (/var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:43737)
      at async Y (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:16:24556) {
    error: 'invalid_grant',
    errorDescription: 'Unknown or invalid refresh token.'
  },
  status: undefined
}

Any advice?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

7 participants