> ## Documentation Index
> Fetch the complete documentation index at: https://docs-staging-quickstart-revamp.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Keeping your user logged in with Auth0.Android

# Auth0.Android Save and Renew Tokens

When an authentication is performed with the `offline_access` scope included, it returns a <Tooltip tip="Refresh Token: Token used to obtain a renewed Access Token without forcing users to log in again." cta="View Glossary" href="/docs/glossary?term=refresh+token">refresh token</Tooltip> that can be used to request a new user token, without forcing the user to perform authentication again.

## Credentials Manager

[Auth0.Android](https://github.com/auth0/Auth0.Android) provides a utility class to streamline the process of storing and renewing credentials. You can access the `accessToken` or `idToken` properties from the [Credentials](https://github.com/auth0/Auth0.Android/blob/master/auth0/src/main/java/com/auth0/android/result/Credentials.java) instance. This is the preferred method to manage user credentials.

Credential Managers are included as part of the Auth0.Android SDK. If this is not yet part of your dependencies, follow the instructions in [Auth0.Android](/docs/libraries/auth0-android).

There are two classes you can use to manage credentials:

* `CredentialsManager` stores data in plain text.
* `SecureCredentialsManager` encrypts the data before storing it, using a combination of RSA and AES algorithms along with [Android KeyStore](https://developer.android.com/reference/java/security/KeyStore.html).

## Using the CredentialsManager class

### Set up the CredentialsManager

Create a new instance by passing an `AuthenticationAPIClient` and a `Storage` implementation.

```kotlin lines
val auth0 = Auth0(this)
val apiClient = AuthenticationAPIClient(auth0)
val manager = CredentialsManager(apiClient, SharedPreferencesStorage(this))
```

### Current state of the authentication

Stored credentials are considered valid if they have not expired or can be refreshed. Check if a user has already logged in.

```kotlin lines
val loggedIn = manager.hasValidCredentials()
```

To log the user out of your application, remove the stored credentials and direct them to the login screen.

```kotlin lines
manager.clearCredentials()
```

### Retrieving credentials

Because the credentials may need to be refreshed against Auth0 Servers, this method is asynchronous. Pass a callback implementation where you want to receive the credentials. Credentials returned by this method upon success are always valid.

```kotlin lines
manager.getCredentials(object: Callback<Credentials, CredentialsManagerException>() {
    override fun onSuccess(credentials: Credentials) {
        // Use credentials
    }

    override fun onFailure(error: CredentialsManagerException) {
        // No credentials were previously saved or they couldn't be refreshed
    }
})
```

If the `accessToken` has expired, the manager automatically uses the `refreshToken` and renews the credentials for you. New credentials will be stored for future access.

### Save new credentials

You can save the credentials obtained during authentication in the manager.

```text lines
manager.saveCredentials(credentials)
```

## Using the SecureCredentialsManager class

### Set up the SecureCredentialsManager

Create a new instance by passing a valid android `Context`, an `AuthenticationAPIClient` and a `Storage` implementation.

```kotlin lines
val auth0 = Auth0(this)
val apiClient = AuthenticationAPIClient(auth0)
val manager = SecureCredentialsManager(this, apiClient, SharedPreferencesStorage(this))
```

The methods to obtain, save, check for existence, and clear the credentials are the same as described in the section above.

### Pre-authenticate the user

This class provides optional functionality for additional authentication using the device's configured lock screen.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  If Lock Screen Security is set to something different than PIN, Pattern, Password or Fingerprint, this feature isn't available.
</Callout>

Call the method below to enable the authentication. Pass a valid `Activity` context, a request code, and two optional strings to use as title and description for the lock screen.

Also define a request code constant so that the request code coming from the activity result can be matched up.

```kotlin lines
companion object {
  const val RC_UNLOCK_AUTHENTICATION = 123
}

// Called from an Activity
val available = manager.requireAuthentication(this, RC_UNLOCK_AUTHENTICATION, getString(R.string.unlock_authentication_title), getString(R.string.unlock_authentication_description))
```

If the feature is enabled, the manager will prompt the user to authenticate using the configured lock screen. The result of this call will be obtained in the `onActivityResult` method of the activity passed before as first parameter. If the feature was not enabled, lock screen authentication will be skipped.

After checking that the received request code matches the one used in the configuration step, redirect the received parameters to the manager to finish the authentication. The credentials will yield to the original callback.

```kotlin lines
override fun onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == RC_UNLOCK_AUTHENTICATION && manager.checkAuthenticationResult(requestCode, resultCode)) {
        return
    }

    super.onActivityResult(requestCode, resultCode, data)
}
```

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  The `onActivityResult` method was deprecated on 2021 in favor of the new [Activity Result APIs](https://developer.android.com/training/basics/intents/result). However, the Auth0.Android SDK is not compatible with these contracts. You can continue to use the deprecated methods safely.
</Callout>

### Handling usage exceptions

If an unexpected event occurs while trying to save or retrieve the Credentials, a `CredentialsManagerException` will be thrown. These are some of the failure scenarios you can expect:

* The Credentials to be stored are invalid (for example, some of the following fields are not defined: `access_token`, `id_token` or `expires_at`).
* The stored Credentials have expired but there is no refresh token available to renew them automatically.
* The device's lock screen security settings have changed (for example the security PIN code changed). Even when `hasCredentials` returns true, the encryption keys will be deemed invalid. Until `saveCredentials` is called again, it won't be possible to decrypt any previously existing content because they previously used keys are not the same as the new ones.
* The device is not compatible with some of the cryptography algorithms required by the `SecureCredentialsManager` class. This is considered a catastrophic event and is the only exception that will prevent you from using this implementation. This scenario happens when the OEM has modified the Android ROM of the device, removing some of the algorithms officially included in every Android distribution. Nevertheless, you can check if this is the case in the exception instance itself by calling the `isDeviceIncompatible` method. By doing so you can decide the fallback implementation for storing the credentials, such as using the regular `CredentialsManager` class.
