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

Token refresh failure reason unclear #747

Open
6 tasks done
anthony-unmind opened this issue Jun 18, 2024 · 4 comments
Open
6 tasks done

Token refresh failure reason unclear #747

anthony-unmind opened this issue Jun 18, 2024 · 4 comments
Labels
bug This points to a verified bug in the code

Comments

@anthony-unmind
Copy link

Checklist

Description

When calling SecureCredentialsManager.getCredentials or CredentialsManager.getCredentials, an attempt to refresh the token will be made if necessary.

If the refresh attempt fails, an error is thrown with the message: An error occurred while trying to use the Refresh Token to renew the Credentials (here and here)

The issue is that this error is thrown whether the refresh token was also expired (requiring the user to authenticate again) or there was simply a network error.

This makes it impossible for consumer code to decide whether to force the user to logout and reauthenticate, or to at least make a decision about trying again or falling back to offline mode until network conditions have improved.

The Auth0.swift library, by contrast, throws two different errors allowing us to detect general errors verses a user who really should be logged out.

Reproduction

This can be consistently reproduced in an application that relies on the CredentialsManager classes to retrieve (an automatically refresh) tokens.

Test 1 – Genuinely expired user session

  • Add a try/catch around any code that attempts to use the getCredentails methods.
  • Authenticate
  • Close the app and wait however long it takes for both the auth token AND refresh tokens to expire
  • Open the app and trigger the use of getCredentials
  • The error message mentioned above is thrown

Test 2 – Network error

  • Add a try/catch around any code that attempts to use the getCredentails methods.
  • Authenticate
  • Close the app and go into Airplane Mode
  • Wait however long it takes for the auth token to expire (but NOT so long that the refresh token expires)
  • Open the app and trigger the use of getCredentials
  • Because in airplane mode, the attempt to refresh will fail
  • The error message mentioned above is thrown

The identical error message in both scenarios makes it difficult to know what to do next.

Additional context

For background, we are relying on both libraries (Android and iOS) via the react-native-auth0 package

Auth0.Android version

2.10.2

Android version(s)

@anthony-unmind anthony-unmind added the bug This points to a verified bug in the code label Jun 18, 2024
@bennycao
Copy link
Contributor

@anthony-unmind not sure if this will answer your query about what sort of exception is thrown. The cause which is a AuthenticationException of CredentialsManagerException will give you a clue as to what type of exception it is. This type has properties such as isInvalidRefreshToken , isNetworkError, http statusCode etc...

@anthony-unmind
Copy link
Author

anthony-unmind commented Jun 26, 2024

Hi @bennycao

The full object we receive in our catch block is fairly detailed, but I don't see anything that indicates reason for failure (eg network issue)

For reference, here is the error we catch in our React Native app:

{
  "nativeStackAndroid": [
    {
      "lineNumber": 568,
      "file": "SecureCredentialsManager.kt",
      "methodName": "continueGetCredentials$lambda$3",
      "class": "com.auth0.android.authentication.storage.SecureCredentialsManager"
    },
    {
      "lineNumber": 0,
      "file": null,
      "methodName": "$r8$lambda$vhEXmcnej0N0f6vk6r6n2MpvTso",
      "class": "com.auth0.android.authentication.storage.SecureCredentialsManager"
    },
    {
      "lineNumber": 12,
      "file": null,
      "methodName": "run",
      "class": "com.auth0.android.authentication.storage.SecureCredentialsManager$$ExternalSyntheticLambda1"
    },
    {
      "lineNumber": 1137,
      "file": "ThreadPoolExecutor.java",
      "methodName": "runWorker",
      "class": "java.util.concurrent.ThreadPoolExecutor"
    },
    {
      "lineNumber": 637,
      "file": "ThreadPoolExecutor.java",
      "methodName": "run",
      "class": "java.util.concurrent.ThreadPoolExecutor$Worker"
    },
    {
      "lineNumber": 1012,
      "file": "Thread.java",
      "methodName": "run",
      "class": "java.lang.Thread"
    }
  ],
  "userInfo": null,
  "message": "An error occurred while trying to use the Refresh Token to renew the Credentials.",
  "code": "a0.invalid_state.credential_manager_exception"
}

@mounarezgui
Copy link

mounarezgui commented Oct 10, 2024

In case anyone facing the same issue:

This makes it impossible for consumer code to decide whether to force the user to logout and reauthenticate, or to at least make a decision about trying again or falling back to offline mode until network conditions have improved.

As a workaround you can use val authenticated = manager.hasValidCredentials(), which returns true if you have a valid token or a valid refresh token.
if(authenticated) perform your retry mechanism/offline mode... otherwise you should present the login screen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This points to a verified bug in the code
Projects
None yet
Development

No branches or pull requests

3 participants