auth0 / auth0-spa-js

Auth0 authentication for Single Page Applications (SPA) with PKCE

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cannot handle login required error when refresh token expires

chriskuech opened this issue · comments

Describe the problem you'd like to have solved

We are getting bugs from users complaining that the app fails if they keep their browser tab open for 12+ hours because the refresh token expires under the hood. I want to handle this error and execute some code (logging out the user from the app).

Describe the ideal solution

Ideally, auth0 exposes the MissingRefreshTokenError error for us to handle in our code, though it appears internally you handle by checking error structure with an unexposed constant.

Alternatives and current work-arounds

Alternative solution could be proactively checking the refresh token (#813)

We currently have no workarounds, so any would be appreciated.

Additional context

Thanks for reaching out, can you elaborate on what it means for the application for fail?

Typically our SDK should be able to handle when the refresh token expired. What happens in that case is, when you call getTokenSilently, it will try get a new token. If it can't it can throw a couple of errors:

  • When there is no valid refresh token and useRefreshTokensFallback is set to false, missing_refresh_token is thrown.
  • When there is no valid refresh token and useRefreshTokensFallback is set to true (or omitted), it throws a login_required error, indicating Auth0 is unable to send us a new pair of tokens because the session expired.
  • When there is a valid refresh token and when useRefreshTokensFallback is set to true (or omitted), it will throw login_required if that fails. When useRefreshTokensFallback is set. to false, it fails with invalid_grant.

These errors should typically allow you to react accordingly and log the user in again, or log them out as needed.

Ideally, auth0 exposes the MissingRefreshTokenError error for us to handle in our code

I think we can definetly look into exposing this, but you should be able to use the following:

try {
  const token = await client.getTokenSIlently();
} catch (e) {
   if (['login_required', 'missing_refresh_token', 'invalid_grant'].includes(e.error) {
     this.logout({
       onRedirect: async () => {}
     });
   }
   throw e;
}

Regardless, exported it in #1043 as it was missing, thanks for reporting that!

@frederikprijck thank you for the diligent solution!