Auth0 Android SDK

repository·main·Indexed 43 days ago

https://github.com/auth0/auth0.android

A secure SDK for integrating Auth0 authentication services into Android applications. Supports Universal Login, Credentials Manager for token management, and Trusted Web Activity (TWA). Requires Android API 26+, Java 17+, and provides a V4 Migration Guide. Key components include AuthenticationAPIClient, WebAuthProvider, and CredentialsManager.

Tokens
41.9K
Snippets
134
Records
170
Agent score
54%

What's inside Auth0 Android SDK

  1. Explore Auth0.Android usage examples

    main
    The auth0.android repository provides a comprehensive set of examples organized by functional area. You can find specific implementation details for Web Auth, the Authentication API, and various advanced features in the examples/ directory.
  2. Maintain Java interoperability for public methods

    main

    The SDK supports both Kotlin and Java consumers. Adding a suspend function as a public method will break compatibility for Java users, as they cannot call coroutine-based methods directly.

    Requirement: Every new asynchronous public method must provide both a suspend form (for Kotlin) and a callback form (for Java). Always verify interoperability by writing a Java test.

  3. Configure BiometricPolicy for authentication

    main

    The BiometricPolicy determines how often a user must re-authenticate to access credentials.

    Policy Types:

    • BiometricPolicy.Always: Requires authentication every single time credentials are accessed (Default).
    • BiometricPolicy.Session(timeoutInSeconds): Requires authentication only if the specified timeout has passed since the last successful authentication.
    • BiometricPolicy.AppLifecycle(timeoutInSeconds): Persists the authentication session for the lifetime of the app process. The default timeout is 1 hour (3600 seconds).
    // Session policy: 5 minutes
    val sessionPolicy = LocalAuthenticationOptions.Builder()
        .setPolicy(BiometricPolicy.Session(300))
        .build()
    
    // App lifecycle policy: 1 hour default
    val appLifecyclePolicy = LocalAuthenticationOptions.Builder()
        .setPolicy(BiometricPolicy.AppLifecycle())
        .build()
  4. Migrate from Management API (UsersAPIClient) to Backend Endpoints

    main

    Management API support (including UsersAPIClient, ManagementException, and ManagementCallback) has been removed from the mobile SDK.

    Migration Strategy: Instead of calling the Management API directly from your mobile app, you should:

    1. Create a dedicated endpoint on your own backend (e.g., PATCH /me/metadata).
    2. Call that endpoint from your app, passing the user's access token as a Bearer token in the Authorization header.
    3. On your backend, use a machine-to-machine token (via Client Credentials flow) to call the Auth0 Management API with the required scopes.
  5. Use the dual async API pattern for asynchronous methods

    main

    The SDK provides two ways to consume asynchronous public methods to support both Kotlin Coroutines and Java consumers:

    1. Callback-based: For Java compatibility and standard callback patterns.
    2. Suspend functions: For idiomatic Kotlin Coroutine usage.

    When interacting with the SDK, choose the pattern that matches your language/concurrency model.

    // ✅ Both forms are provided for async public methods
    fun getCredentials(callback: Callback<Credentials, CredentialsManagerException>)
    suspend fun awaitCredentials(): Credentials
  6. Understand the Auth0.Android error hierarchy

    main

    When handling errors from the Auth0.Android SDK, you should use the provided exception hierarchy rather than catching generic Exception or RuntimeException types. This ensures type safety and prevents brittle code based on string matching error messages.

    The hierarchy is structured as follows:

    • Auth0Exception (Base class)
      • AuthenticationException
      • CredentialsManagerException
      • DPoPException
      • MyAccountException
  7. Use CredentialsManager for basic credential management

    main

    The CredentialsManager class provides a high-level way to manage user credentials, including checking for existence, storing them, retrieving them, and handling automatic token refreshing.

    To enable automatic refreshing when tokens expire, you must include the offline_access scope during the login process to ensure a refresh_token is received.

    Key Requirements for Saving Credentials:

    • The Credentials object must contain an expires_at value.
    • The Credentials object must contain at least an access_token or an id_token.
    • If these values are missing, saveCredentials will throw a CredentialsManagerException.
    val authentication = AuthenticationAPIClient(account)
    val storage = SharedPreferencesStorage(this)
    val manager = CredentialsManager(authentication, storage)
  8. Understand Upstream Session Expiry (session_expiry)

    main

    Auth0 can include a session_expiry claim in the ID token, which acts as an absolute ceiling (in Unix seconds) for how long a local session can live. This ceiling is independent of access token expiry and cannot be extended by refresh token renewal.

    Behavior:

    • The ceiling is persisted from the ID token at login.
    • On every getCredentials call, if the ceiling is reached, the stored credentials are cleared and the call fails with CredentialsManagerException.SESSION_EXPIRED.
    • A ~30-second clock-skew leeway is applied.

    Important Implementation Note: The session_expiry value must be in Unix seconds. If you provide a millisecond-magnitude value (e.g., 1700000000000), the SDK will treat it as having no ceiling. Always divide millisecond timestamps by 1000 when emitting this claim from an Auth0 Action.

  9. Customize the networking client behavior

    main

    The Auth0 SDK allows you to customize how network requests are made by providing a NetworkingClient to the Auth0 instance. You can use the DefaultClient.Builder to configure common settings like timeouts, logging, and headers, or provide a custom implementation of the NetworkingClient interface for advanced needs like proxy support or reusing an existing networking stack.

    val account = Auth0.getInstance("{YOUR_CLIENT_ID}", "{YOUR_DOMAIN}")
    account.networkingClient = netClient
  10. Understand CredentialsManager behavior changes in v4

    main

    Global Executor

    In v4, CredentialsManager uses a process-wide single-thread executor instead of creating a per-instance executor. If multiple CredentialsManager instances are backed by the same Auth0 object, renewal operations are now serialized. This eliminates race conditions and duplicate invalid_grant errors during token rotation, though a slow renewal will block other callers on that executor.

    clearCredentials() behavior

    In v4, clearCredentials() now calls Storage.removeAll(). This clears all values in the storage, including API credentials stored for specific audiences. If you need to preserve specific stored data while removing primary tokens, use a separate Storage instance for those credentials.

    Storage Interface

    The Storage interface now includes a removeAll() method. Existing custom Storage implementations will work without changes, but you should override removeAll() if your custom storage is used with clearCredentials() to ensure proper cleanup.

  11. Use Partial Custom Tabs (Bottom Sheet and Side Sheet)

    main

    Instead of a full-screen browser tab, you can present the authentication flow as a bottom sheet (on compact screens) or a side sheet (on larger screens like tablets).

    Browser Compatibility & Fallback:

    • Bottom sheet requires Chrome 107+.
    • Side sheet requires Chrome 120+.

    If the user's browser is older or incompatible, the SDK automatically falls back to a standard full-screen Custom Tab or a full-screen browser tab. You can safely enable these options without breaking the experience for users on older browsers.

    // Example: Bottom Sheet configuration
    val ctOptions = CustomTabsOptions.newBuilder()
        .withInitialHeight(700)          // initial height in dp
        .withResizable(true)             // allow the user to drag to resize (default)
        .withToolbarCornerRadius(16)     // rounded top corners (0–16 dp)
        .build()
    
    WebAuthProvider.login(account)
        .withCustomTabsOptions(ctOptions)
        .start(this, callback)