Hi Auth0, I started using Auth0 for a toy project a couple of months ago with 5 or so users (just family). This was around the time when rotating refresh tokens were made available, so I chose to use that for my SPA (React). One by one users (including myself) have encountered an issue whereby a call to the token endpoint results in a 403 and an Error: Unknown or invalid refresh token.
I have so far managed to resolve this by asking users to quite hackily, go into their local storage, and delete the key for the auth0SPA, which then allows them to perform a login. Today, I had the issue happen to me again, and upon looking at the refresh tokenās expiry, I realised that it expired a couple of days ago. I then went into my SPA settings on the Auth0 portal, and saw that the lifetime of my refresh tokens is set to 30 days. So iām now thinking that the 2 are related. I am aware that this can be extended to 3 months, and itās what I will be doing.
My questions:
Am I correct in understanding that users MUST log in again at least once ever 3 months? I.e. there is no option whatsoever that a user is logged in ad infinitum. Again, Iām ok with this, and understand why it is so for security reasons.
Should my code be the one deleting the Auth0SPA entry in my local storage? This makes little sense to me, since I believe the SPA.js library should be able to handle this by itself. What should my code be doing when the refresh token has expired?
EDIT: While I was reviewing the code, I noticed that Iām using cacheLocation="localstorage" when creating my Auth0Provider. Upon removing this, I was unable to reproduce the issue. The reason I had chosen to specify the cacheLocation as localstorage, was because emitting this would result in the website not working on Safari. Is it possible that the library is not handling refresh token expiry correctly when cache location is localstorage?
Yes thatās correct, our rotating refresh tokens have this default absolute expiry of 30 days, after which your users must log in again
As long as you can handle the invalid refresh token error, instead of deleting local storage, you should just put your users back through an interactive login flow, either by using loginWithRedirect or loginWithPopup. This is the only way you can get a new refresh token, but doing this will also refresh your local storage state so that it contains the correct and valid tokens. No need to delete manually.
^ This last point is something we could be doing better at explaining or showing how itās done, which I will try to solve.
Also your point about Safari is correct - if you do not use local storage, you are then relying on Auth0 being able to read your Auth0 session cookie, which it is unable to do in browsers like Safari and Brave that block third-party cookies by default.
The error is being thrown from createAuth0Client. Since there is not a valid client its not possible to redirect or popup a login. The only way around this is to manually delete the token from session storage.
By specifying to not use refresh tokens in the failure case, it does allow me to create a client and cause a login. However this doesnāt clear out the invalid refresh token and now Iām in an infinite login prompt āinvalid refresh tokenā loop.
The only resolution I have found is to do one of 2 things:
set useRefreshTokens to false
set cacheLocation to āmemoryā instead of ālocalstorageā
Hi Nick, thanks for taking the time to play around with this. I too observed that the SPA code on github has the logout method clean up the data in local storage, however I didnāt consider reattempting to create the Auth0Client with the useRefreshTokens set to false. Like you yourself said though, itās till quite hacky, and I think the API should be able to handle this by itself. In my code I decided to just remove Auth0ās key from local storage as part of my catch block, but I hope that this will bee addressed down the line.