Auth0.Android icon indicating copy to clipboard operation
Auth0.Android copied to clipboard

Token refresh failure reason unclear

Open anthony-unmind opened this issue 1 year ago • 4 comments

Checklist

  • [X] The issue can be reproduced in the Auth0.Android sample app (or N/A).
  • [X] I have looked into the Readme, Examples, and FAQ and have not found a suitable solution or answer.
  • [X] I have looked into the API documentation and have not found a suitable solution or answer.
  • [X] I have searched the issues and have not found a suitable solution or answer.
  • [X] I have searched the Auth0 Community forums and have not found a suitable solution or answer.
  • [X] I agree to the terms within the Auth0 Code of Conduct.

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 avatar Jun 18 '24 11:06 anthony-unmind

@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...

bennycao avatar Jun 26 '24 00:06 bennycao

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"
}

anthony-unmind avatar Jun 26 '24 09:06 anthony-unmind

@anthony-unmind the Exception type for reference is https://github.com/auth0/Auth0.Android/blob/main/auth0/src/main/java/com/auth0/android/authentication/AuthenticationException.kt#L114 This exception can be wrapped inside https://github.com/auth0/Auth0.Android/blob/main/auth0/src/main/java/com/auth0/android/authentication/storage/CredentialsManagerException.kt

bennycao avatar Jun 27 '24 01:06 bennycao

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.

mounarezgui avatar Oct 10 '24 11:10 mounarezgui

Hi @anthony-unmind , We have made a new release on Android https://github.com/auth0/Auth0.Android/releases/tag/3.2.1 to address this issue . It will give more defined error types for such scenarios. Meanwhile you can use the cause property as suggested by @bennycao. Since you are using react native client we will plan to update the Android version on react-native on the coming releases . I am closing this thread for now. Please feel free to open a new one on react-native repo if you have any other concerns

pmathew92 avatar Dec 11 '24 08:12 pmathew92