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

# Add Login to Your Flutter Application

> This guide demonstrates how to integrate Auth0 with any Flutter app using the Auth0 Flutter SDK.

export const HowToSchema = () => <script type="application/ld+json">
    {'{"@context":"https://schema.org","@type":"HowTo"}'}
  </script>;

<HowToSchema />

<Accordion title="Use AI to integrate Auth0" icon="microchip-ai" iconType="solid" defaultOpen>
  If you use an AI coding assistant like Claude Code, Cursor, or GitHub Copilot, you can add Auth0 authentication automatically in minutes using [agent skills](https://agentskills.io/home).

  **Install:**

  ```bash theme={null}
  npx skills add auth0/agent-skills --skill auth0-quickstart --skill auth0-flutter-native
  ```

  **Then ask your AI assistant:**

  ```text theme={null}
  Add Auth0 authentication to my Flutter app
  ```

  Your AI assistant will automatically create your Auth0 application, fetch credentials, add the auth0\_flutter SDK dependency, configure the Android and iOS callback URLs, and implement Web Auth login/logout with secure credential storage. [Full agent skills documentation →](/quickstart/agent-skills)
</Accordion>

This guide demonstrates how to integrate Auth0 with a Flutter application using the [Auth0 Flutter SDK](https://github.com/auth0/auth0-flutter). This guide covers setup for **Android**, **iOS**, and **macOS** platforms.

<Info>
  The Auth0 Flutter SDK also supports **Web** and **Windows** (beta). These platforms have dedicated quickstarts:

  * [Flutter Web Quickstart](/docs/quickstart/spa/flutter) — for Flutter apps targeting the browser
  * [Flutter Windows Quickstart](/docs/quickstart/native/flutter-windows) — for Flutter desktop apps on Windows (beta)
</Info>

## Get Started

<Steps>
  <Step title="Create a new Flutter project" stepNumber={1}>
    Create a new Flutter project for this quickstart.

    **In your terminal:**

    1. Navigate to your workspace directory
    2. Run: `flutter create auth0_flutter_sample`
    3. Navigate into the project: `cd auth0_flutter_sample`
    4. Open in your IDE:
       * **VS Code**: `code .`
       * **Android Studio**: `open -a "Android Studio" .`

    ```shellscript theme={null}
    # Create new Flutter project
    flutter create auth0_flutter_sample

    # Navigate into project directory
    cd auth0_flutter_sample

    # Open in VS Code
    code .
    ```

    <Tip>
      This creates a modern Flutter app with the latest project structure. Run `flutter doctor` to verify your environment is set up correctly.
    </Tip>
  </Step>

  <Step title="Install the Auth0 Flutter SDK" stepNumber={2}>
    Add the Auth0 Flutter SDK to your project using the Flutter CLI.

    ```shellscript theme={null}
    flutter pub add auth0_flutter
    ```

    This will add `auth0_flutter` to your `pubspec.yaml` dependencies:

    ```yaml pubspec.yaml lines theme={null}
    dependencies:
      auth0_flutter: ^2.0.0-beta.1
    ```

    <Tip>
      The Auth0 Flutter SDK requires **Flutter 3.24.0+** and **Dart 3.5.0+**. Run `flutter doctor` to verify your environment meets these requirements.
    </Tip>
  </Step>

  <Step title="Setup your Auth0 App" stepNumber={3}>
    Next up, you need to create a new app on your Auth0 tenant and configure the callback URLs.

    1. Head to the [Auth0 Dashboard](https://manage.auth0.com/dashboard/)
    2. Click on **Applications** > **Applications** > **Create Application**
    3. In the popup, enter a name for your app, select `Native` as the app type and click **Create**
    4. Switch to the **Settings** tab on the Application Details page
    5. Note down the **Domain** and **Client ID** values - you'll need these later

    On the **Settings** tab, configure the following URLs based on your target platform(s):

    **Allowed Callback URLs:**

    <Tabs>
      <Tab title="Android">
        ```text theme={null}
        https://{yourDomain}/android/{yourPackageName}/callback
        ```
      </Tab>

      <Tab title="iOS">
        ```text theme={null}
        https://{yourDomain}/ios/{yourBundleIdentifier}/callback,
        {yourBundleIdentifier}://{yourDomain}/ios/{yourBundleIdentifier}/callback
        ```
      </Tab>

      <Tab title="macOS">
        ```text theme={null}
        https://{yourDomain}/macos/{yourBundleIdentifier}/callback,
        {yourBundleIdentifier}://{yourDomain}/macos/{yourBundleIdentifier}/callback
        ```
      </Tab>
    </Tabs>

    **Allowed Logout URLs:**

    Add the same URLs from the callback configuration above to the **Allowed Logout URLs** field.

    <Info>
      **Allowed Callback URLs** are a critical security measure to ensure users are safely returned to your application after authentication. Without a matching URL, the login process will fail.

      **Allowed Logout URLs** are essential for providing a seamless user experience upon signing out. Without a matching URL, users will not be redirected back to your application after logout.

      For example, if your Auth0 domain is `example.us.auth0.com` and your Android package name is `com.example.myapp`, your Android callback URL would be: `https://example.us.auth0.com/android/com.example.myapp/callback`
    </Info>

    <Warning>
      **Important**: Ensure the package name (Android) or bundle identifier (iOS/macOS) in your callback URLs matches your actual app identifier. If authentication fails, verify these values are identical.
    </Warning>
  </Step>

  <Step title="Configure Your Application" stepNumber={4}>
    Platform-specific configuration is required to enable the authentication flow. Follow the instructions for each platform you're targeting.

    <Tabs>
      <Tab title="Android">
        Open the `android/app/build.gradle` file and add the following manifest placeholders inside `android > defaultConfig`:

        ```groovy android/app/build.gradle lines theme={null}
        android {
            // ...
            defaultConfig {
                // Add the following line
                manifestPlaceholders += [auth0Domain: "{yourDomain}", auth0Scheme: "https"]
            }
            // ...
        }
        ```

        Replace `{yourDomain}` with your Auth0 domain (e.g., `example.us.auth0.com`).

        **https scheme**

        To use `https` scheme for your callback url, set up [Android app links](https://auth0.com/docs/get-started/applications/enable-android-app-links-support) for your application.

        **For Biometric Authentication (Optional):**

        If you plan to use biometric authentication, update your `MainActivity.kt` to extend `FlutterFragmentActivity`:

        ```kotlin android/app/src/main/kotlin/.../MainActivity.kt lines theme={null}
        import io.flutter.embedding.android.FlutterFragmentActivity

        class MainActivity: FlutterFragmentActivity() {
        }
        ```
      </Tab>

      <Tab title="iOS">
        To use Universal Links (HTTPS callback URLs) on iOS 17.4+, configure an Associated Domain:

        1. Open your app in Xcode: `open ios/Runner.xcworkspace`
        2. Select the **Runner** target and go to **Signing & Capabilities**
        3. Click **+ Capability** and add **Associated Domains**
        4. Add the entry: `webcredentials:{yourDomain}`
        5. In the [Auth0 Dashboard](https://manage.auth0.com/#/applications), go to **Settings > Advanced Settings > Device Settings**
        6. In the **iOS** section, set your **Team ID** and **App ID** (bundle identifier)

        <Info>
          Universal Links configuration is optional. Skip this if you don't need Universal Links support - the SDK will fall back to custom URL schemes automatically.
        </Info>
      </Tab>

      <Tab title="macOS">
        Follow the same steps as iOS, but open `macos/Runner.xcworkspace` instead.
      </Tab>
    </Tabs>

    <Warning>
      **Android**: Ensure the `auth0Domain` value matches your Auth0 domain exactly. If authentication fails, verify this value is identical to the domain shown in your Auth0 Dashboard.

      **iOS/macOS**: Universal Links require a paid Apple Developer account and iOS 17.4+/macOS 14.4+. On older versions, the SDK automatically falls back to custom URL schemes.
    </Warning>
  </Step>

  <Step title="Implement Login and Logout" stepNumber={5}>
    [Universal Login](https://auth0.com/docs/authenticate/login/auth0-universal-login) is the easiest way to set up authentication in your application. We recommend using it for the best experience, best security, and the fullest array of features.

    **Implement Login:**

    Import the Auth0 Flutter SDK and create an `Auth0` instance:

    ```dart lib/auth_service.dart lines theme={null}
    import 'package:auth0_flutter/auth0_flutter.dart';

    class AuthService {
      final auth0 = Auth0('{yourDomain}', '{yourClientId}');

      Future<Credentials> login() async {
        final credentials = await auth0.webAuthentication().login(useHTTPS: true);

        // Access token -> credentials.accessToken
        // ID token -> credentials.idToken
        // User profile -> credentials.user

        return credentials;
      }
    }
    ```

    **Implement Logout:**

    ```dart lib/auth_service.dart lines theme={null}
    Future<void> logout() async {
      await auth0.webAuthentication().logout(useHTTPS: true);

      // User is now logged out
      // Credentials have been cleared from secure storage
    }
    ```

    <Info>
      **iOS/macOS**: The `useHTTPS: true` parameter enables Universal Links on iOS 17.4+ and macOS 14.4+ for enhanced security.

      **Android**: If you are using a custom scheme, pass this scheme to the login method so that the SDK can route to the login page and back again correctly:

      ```dart theme={null}
      await auth0.webAuthentication(scheme: 'YOUR CUSTOM SCHEME').login();
      ```
    </Info>
  </Step>

  <Step title="Show User Profile Information" stepNumber={6}>
    The user profile is automatically retrieved when the user logs in. The `Credentials` object contains a `user` property with all the user profile information, populated by decoding the ID token.

    ```dart lib/profile_screen.dart lines theme={null}
    void displayUserProfile(Credentials credentials) {
      final user = credentials.user;
      
      print('User ID: ${user.sub}');
      print('Email: ${user.email}');
      print('Name: ${user.name}');
      print('Picture: ${user.pictureUrl}');
      print('Nickname: ${user.nickname}');
    }
    ```

    <Tip>
      Request the appropriate scopes during login to access specific user profile fields. The default scopes are `openid`, `profile`, `email`, and `offline_access`.
    </Tip>
  </Step>

  <Step title="Run your app" stepNumber={7}>
    Build and run your Flutter application.

    **In your terminal:**

    ```shellscript theme={null}
    # List available devices
    flutter devices

    # Run on Android
    flutter run -d android

    # Run on iOS Simulator
    flutter run -d ios

    # Run on macOS
    flutter run -d macos
    ```

    **Expected flow:**

    1. App launches with your login UI
    2. User taps **Log In** → Browser/Custom Tab opens with Auth0 Universal Login
    3. User completes authentication
    4. Browser redirects back to your app
    5. User is now authenticated and credentials are stored
  </Step>
</Steps>

<Check>
  **Checkpoint**

  You should now have a fully functional Auth0 login experience in your Flutter application. The app uses secure browser-based authentication and automatically stores credentials for session persistence.
</Check>

***

## Troubleshooting & Advanced Usage

<Accordion title="Common Issues & Solutions">
  ### Callback URL Mismatch

  **Symptom**: Error "redirect\_uri\_mismatch" or authentication fails silently.

  **Solutions:**

  1. Check **Allowed Callback URLs** in Auth0 Dashboard match your app configuration exactly
  2. Verify the scheme (`https://` vs `http://`)
  3. Ensure the package name (Android) or bundle identifier (iOS/macOS) is correct
  4. Check for trailing slashes

  ### Android: Chrome Custom Tab Doesn't Open

  **Symptom**: Nothing happens when calling `login()`.

  **Fix:**

  1. Verify `manifestPlaceholders` are correctly set in `build.gradle`
  2. Ensure internet permission is in `AndroidManifest.xml`:
     ```xml theme={null}
     <uses-permission android:name="android.permission.INTERNET" />
     ```
  3. Check that Chrome or another browser is installed on the device

  ### iOS: "Open in App" Alert

  **Symptom**: Alert box appears asking to open in your app.

  **Fix:** This is expected behavior with `ASWebAuthenticationSession`. To remove it:

  * Use Universal Links (requires iOS 17.4+ and paid Apple Developer account)
  * Or set `useEphemeralSession: true` (disables SSO):

  ```dart expandable theme={null}
  await auth0.webAuthentication().login(
    useHTTPS: true,
    useEphemeralSession: true,
  );
  ```

  ### Authentication cancelled by user

  Handle gracefully in your error handling:

  ```dart expandable theme={null}
  try {
    final credentials = await auth0.webAuthentication().login(useHTTPS: true);
    // Handle successful login
  } on WebAuthenticationException catch (e) {
    if (e.code == 'USER_CANCELLED') {
      showMessage('Login was cancelled');
    } else {
      showMessage('Login failed: ${e.message}');
    }
  }
  ```
</Accordion>

<Accordion title="Handling Credentials">
  The Auth0 Flutter SDK includes a built-in Credentials Manager that securely stores user credentials. On mobile platforms, credentials are encrypted and stored in the platform's secure storage (Keychain on iOS/macOS, encrypted SharedPreferences on Android).

  ### Check for Stored Credentials

  Before prompting the user to log in, check if valid credentials already exist:

  ```dart lib/auth_service.dart expandable lines theme={null}
  Future<bool> checkAuthentication() async {
    return await auth0.credentialsManager.hasValidCredentials();
  }
  ```

  ### Retrieve Stored Credentials

  Retrieve credentials to access tokens or user information. The Credentials Manager automatically refreshes expired tokens when possible:

  ```dart lib/auth_service.dart expandable lines theme={null}
  Future<Credentials> getCredentials() async {
    return await auth0.credentialsManager.credentials();
  }
  ```

  <Tip>
    You don't need to manually store credentials after login—the SDK handles this automatically. You also don't need to manually refresh tokens; the Credentials Manager refreshes them when needed.
  </Tip>
</Accordion>

<Accordion title="Error Handling">
  Handle authentication errors gracefully to provide a good user experience.

  ```dart lib/auth_service.dart expandable lines theme={null}
  import 'package:auth0_flutter/auth0_flutter.dart';

  Future<void> login() async {
    try {
      final credentials = await auth0.webAuthentication().login(useHTTPS: true);
      // Handle successful login
    } on WebAuthenticationException catch (e) {
      if (e.code == 'USER_CANCELLED') {
        // User cancelled the login
        print('Login cancelled by user');
      } else {
        // Handle other errors
        print('Login error: ${e.message}');
      }
    }
  }

  Future<Credentials> getCredentials() async {
    try {
      return await auth0.credentialsManager.credentials();
    } on CredentialsManagerException catch (e) {
      if (e.isNoCredentialsFound) {
        // No stored credentials, user needs to log in
        throw Exception('Please log in first');
      } else if (e.isTokenRenewFailed) {
        // Refresh token expired, re-authentication required
        return await auth0.webAuthentication().login(useHTTPS: true);
      }
      rethrow;
    }
  }
  ```
</Accordion>

<Accordion title="Advanced Flutter Integration">
  ### Enhanced Credential Security with Biometrics

  Implement biometric authentication for credential access on mobile:

  ```dart lib/secure_auth_service.dart expandable lines theme={null}
  class SecureAuthService {
    final auth0 = Auth0('{yourDomain}', '{yourClientId}');
    
    Future<void> enableBiometrics() async {
      // Enable local authentication (Face ID, Touch ID, Fingerprint)
      await auth0.credentialsManager.enableLocalAuthentication(
        title: 'Authenticate to access your account',
        cancelTitle: 'Cancel',
        fallbackTitle: 'Use passcode',
      );
    }
    
    Future<Credentials> getCredentialsWithBiometrics() async {
      // This will now require biometric authentication
      return await auth0.credentialsManager.credentials();
    }
  }
  ```

  <Info>
    **Android**: Requires `MainActivity` to extend `FlutterFragmentActivity` as configured in Step 4.

    **iOS/macOS**: Requires adding `NSFaceIDUsageDescription` to your `Info.plist`.
  </Info>

  ### Custom Scopes and Audience

  Request specific scopes and audience for your API:

  ```dart lib/auth_service.dart expandable lines theme={null}
  Future<Credentials> loginWithCustomScopes() async {
    return await auth0.webAuthentication().login(
      useHTTPS: true,
      scopes: {'openid', 'profile', 'email', 'offline_access', 'read:posts'},
      audience: 'https://myapi.example.com',
      parameters: {'prompt': 'login'},
    );
  }
  ```

  ### Organizations (B2B/Enterprise)

  Authenticate users within a specific organization:

  ```dart lib/auth_service.dart expandable lines theme={null}
  Future<Credentials> loginWithOrganization(String organizationId) async {
    return await auth0.webAuthentication().login(
      useHTTPS: true,
      organizationId: organizationId,
    );
  }

  // Or prompt user to select an organization
  Future<Credentials> loginWithOrganizationName(String organizationName) async {
    return await auth0.webAuthentication().login(
      useHTTPS: true,
      organizationName: organizationName,
    );
  }
  ```
</Accordion>

<Accordion title="Production Deployment">
  ### App Store Preparation

  * Configure Universal Links (iOS) and App Links (Android) for seamless authentication
  * Test on multiple device sizes and OS versions
  * Implement proper error handling for network failures
  * Add ProGuard rules for Android if using code obfuscation
  * Follow platform-specific App Store/Play Store policies

  ### Security Considerations

  * Use the built-in Credentials Manager for production credential storage
  * Enable biometric authentication for sensitive operations
  * Consider certificate pinning for additional API security
  * Implement proper token refresh handling
  * Use `useHTTPS: true` for Universal Links on supported platforms
</Accordion>

***

## Next Steps

Check out the [EXAMPLES.md](https://github.com/auth0/auth0-flutter/blob/main/auth0_flutter/EXAMPLES.md) file in the SDK repository for comprehensive code examples covering advanced scenarios like DPoP, biometric authentication, passwordless login and many more features.
