Skip to content

Latest commit

 

History

History
763 lines (548 loc) · 29.5 KB

EXAMPLES.md

File metadata and controls

763 lines (548 loc) · 29.5 KB

Examples

📱 Web Authentication


Log out

Logging the user out involves clearing the Universal Login session cookie and then deleting the user's credentials from your app.

Call the logout() method in the onPressed callback of your Logout button. Once the session cookie has been cleared, auth0_flutter will automatically delete the user's credentials.

Mobile

If you're using your own credentials storage, make sure to delete the credentials afterward.

// Use a Universal Link logout URL on iOS 17.4+ / macOS 14.4+
// useHTTPS is ignored on Android
await auth0.webAuthentication().logout(useHTTPS: true);
Web
if (kIsWeb) {
  await auth0Web.logout(returnToUrl: 'http://localhost:3000');
}

💡 You need to import the 'flutter/foundation.dart' library to access the kIsWeb constant. If your app does not support other platforms, you can remove this condition.

Sign up

You can make users land directly on the Signup page instead of the Login page by specifying the 'screen_hint': 'signup' parameter. Note that this can be combined with 'prompt': 'login', which indicates whether you want to always show the authentication page or you want to skip if there's an existing session.

Parameters No existing session Existing session
No extra parameters Shows the login page Redirects to the callback URL
'screen_hint': 'signup' Shows the signup page Redirects to the callback URL
'prompt': 'login' Shows the login page Shows the login page
'prompt': 'login', 'screen_hint': 'signup' Shows the signup page Shows the signup page
Mobile
final credentials = await auth0
    .webAuthentication()
    .login(parameters: {'screen_hint': 'signup'});
Web
await auth0Web.loginWithRedirect(
    redirectUrl: 'http://localhost:3000',
    parameters: {'screen_hint': 'signup'});

⚠️ The screen_hint parameter will work with the New Universal Login Experience without any further configuration. If you are using the Classic Universal Login Experience, you need to customize the login template to look for this parameter and set the initialScreen option of the Auth0Lock constructor.

Adding an audience

Specify an audience value to obtain an access token that can be used to make authenticated requests to a backend. The audience value is the API Identifier of your Auth0 API, for example https://example.com/api.

Mobile
final credentials = await auth0
    .webAuthentication()
    .login(audience: 'YOUR_AUTH0_API_IDENTIFIER');
Web
await auth0Web.loginWithRedirect(
    redirectUrl: 'http://localhost:3000',
    audience: 'YOUR_AUTH0_API_IDENTIFIER');

Adding scopes

Specify scopes to request permission to access protected resources, like the user profile.

Mobile

The default scope values are openid, profile, email, and offline_access. Regardless of the values specified, openid is always included.

final credentials = await auth0
    .webAuthentication()
    .login(scopes: {'profile', 'email', 'offline_access', 'read:todos'});
Web

The default scope values are openid, profile, and email. Regardless of the values specified, openid is always included.

await auth0Web.loginWithRedirect(
    redirectUrl: 'http://localhost:3000',
    scopes: {'profile', 'email', 'read:todos'});

Adding custom parameters

Specify additional parameters by passing a parameters map.

Mobile
final credentials = await auth0
    .webAuthentication()
    .login(parameters: {'connection': 'github'});
Web

Custom parameters can be configured globally.

await auth0Web.onLoad(
    parameters: {'connection': 'github'});

Custom parameters can be configured when calling loginWithRedirect. Any globally configured parameter (passed to onLoad()) can be overriden when passing the same custom parameter to loginWithRedirect.

await auth0Web.loginWithRedirect(
    redirectUrl: 'http://localhost:3000',
    parameters: {'connection': 'github'});

ID token validation

auth0_flutter automatically validates the ID token obtained from Web Auth login, following the OpenID Connect specification. This ensures the contents of the ID token have not been tampered with and can be safely used.

Mobile

You can configure the ID token validation by passing an IdTokenValidationConfig instance. Check the API documentation to learn more about the available configuration options.

const config = IdTokenValidationConfig(leeway: 180);
final credentials =
    await auth0.webAuthentication().login(idTokenValidationConfig: config);
Web

You can configure issuer and leeway values through the onLoad() method.

auth0Web
    .onLoad(issuer: 'https://example.com/', leeway: 180)
    .then((final credentials) {
  // ...
});

The max_age value can be configured through loginWithRedirect() and loginWithPopup().

await auth0Web.loginWithRedirect(
    redirectUrl: 'http://localhost:3000',
    maxAge: 7200);

Using SFSafariViewController (iOS only)

auth0_flutter supports using SFSafariViewController as the browser instead of ASWebAuthenticationSession. Note that it can only be used for login, not for logout. According to its docs, SFSafariViewController must be used "to visibly present information to users":

Screenshot of SFSafariViewController's documentation

This is the case for login, but not for logout. Instead of calling logout(), you can delete the stored credentials –using the Credentials Manager's clearCredentials() method– and use 'prompt': 'login' to force the login page even if the session cookie is still present. Since the cookies stored by SFSafariViewController are scoped to your app, this should not pose an issue.

await auth0.webAuthentication().login(
      safariViewController: const SafariViewController(),
      parameters: {'prompt': 'login'}); // Ignore the cookie (if present) and show the login page

💡 SFSafariViewController does not support using a Universal Link as callback URL. See https://auth0.github.io/Auth0.swift/documentation/auth0/useragents to learn more about the differences between ASWebAuthenticationSession and SFSafariViewController.

If you choose to use SFSafariViewController, you need to perform an additional bit of setup. Unlike ASWebAuthenticationSession, SFSafariViewController will not automatically capture the callback URL when Auth0 redirects back to your app, so it is necessary to manually resume the login operation.

1. Configure a custom URL scheme

There is an Info.plist file in the ios/Runner (or macos/Runner, for macOS) directory of your app. Open it and add the following snippet inside the top-level <dict> tag. This registers your iOS/macOS bundle identifier as a custom URL scheme, so the callback URL can reach your app.

<!-- Info.plist -->

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- ... -->
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeRole</key>
            <string>None</string>
            <key>CFBundleURLName</key>
            <string>auth0</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
            </array>
        </dict>
    </array>
<!-- ... -->
</dict>
</plist>

💡 If you're opening the Info.plist file in Xcode and it is not being shown in this format, you can Right Click on Info.plist in the Xcode project navigator and then select Open As > Source Code.

2. Capture the callback URL

Using the UIKit app lifecycle
// AppDelegate.swift

override func application(_ app: UIApplication,
                 open url: URL,
                 options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool {
    WebAuthentication.resume(with: url)
    return super.application(application, open: url, options: options);
}
Using the UIKit app lifecycle with Scenes
// SceneDelegate.swift

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    guard let url = URLContexts.first?.url else { return }
    WebAuthentication.resume(with: url)
}

Errors

Mobile

Web Auth will only throw WebAuthenticationException exceptions. Check the API documentation to learn more about the available WebAuthenticationException properties.

try {
  final credentials = await auth0.webAuthentication().login();
  // ...
} on WebAuthenticationException catch (e) {
  print(e);
}
Web

The web implementation will only throw WebException exceptions. Check the API documentation to learn more about the available WebException properties.

try {
  await auth0Web.loginWithRedirect(redirectUrl: 'http://localhost:3000');
} on WebException catch (e) {
  print(e);
}

Android: Custom schemes

On Android, https is used by default as the callback URL scheme. This works best for Android API 23+ if you're using Android App Links, but in previous Android versions, this may show the intent chooser dialog prompting the user to choose either your app or the browser. You can change this behavior by using a custom unique scheme so that Android opens the link directly with your app.

  1. Update the auth0Scheme manifest placeholder on the android/build.gradle file.
  2. Update the Allowed Callback URLs in the settings page of your Auth0 application.
  3. Pass the scheme value to the webAuthentication() method.
final webAuth = auth0.webAuthentication(scheme: 'YOUR_CUSTOM_SCHEME');

// Login
final credentials = await webAuth.login();

// Logout
await webAuth.logout();

💡 Note that custom schemes can only have lowercase letters.

Go up ⤴

📱 Credentials Manager

This feature is mobile/desktop only; on web, the SPA SDK used by auth0_flutter keeps its own cache. See Handling Credentials on the Web for more details.

The Credentials Manager utility allows you to securely store and retrieve the user's credentials. The credentials will be stored encrypted in Shared Preferences on Android, and in the Keychain on iOS/macOS.

💡 If you're using Web Auth, you do not need to manually store the credentials after login and delete them after logout; auth0_flutter does it automatically.

Check for stored credentials

When the users open your app, check for valid credentials. If they exist, you can retrieve them and redirect the users to the app's main flow without any additional login steps.

final isLoggedIn = await auth0.credentialsManager.hasValidCredentials();

if (isLoggedIn) {
  // Retrieve the credentials and redirect to the main flow
} else {
  // No valid credentials exist, present the login page
}

Retrieve stored credentials

The credentials will be automatically renewed (if expired) using the refresh token. This method is thread-safe.

final credentials = await auth0.credentialsManager.credentials();

💡 You do not need to call credentialsManager.storeCredentials() afterward. The Credentials Manager automatically persists the renewed credentials.

Custom implementations

flutter_auth0 exposes a built-in, default Credentials Manager implementation through the credentialsManager property. You can pass your own implementation to the Auth0 constructor. If you're using Web Auth, this implementation will be used to store the user's credentials after login and delete them after logout.

final customCredentialsManager = CustomCredentialsManager();
final auth0 = Auth0('YOUR_AUTH0_DOMAIN', 'YOUR_AUTH0_CLIENT_ID',
    credentialsManager: customCredentialsManager);
// auth0.credentialsManager is now your CustomCredentialsManager instance

Local authentication

You can enable an additional level of user authentication before retrieving credentials using the local authentication supported by the device, for example PIN or fingerprint on Android, and Face ID or Touch ID on iOS.

const localAuthentication =
    LocalAuthentication(title: 'Please authenticate to continue');
final auth0 = Auth0('YOUR_AUTH0_DOMAIN', 'YOUR_AUTH0_CLIENT_ID',
    localAuthentication: localAuthentication);
final credentials = await auth0.credentialsManager.credentials();

Check the API documentation to learn more about the available LocalAuthentication properties.

⚠️ Enabling local authentication will not work if you're using a custom Credentials Manager implementation. In that case, you will need to build support for local authentication into your custom implementation.

Disable credentials storage

By default, auth0_flutter will automatically store the user's credentials after login and delete them after logout, using the built-in Credentials Manager instance. If you prefer to use your own credentials storage, you need to disable the built-in Credentials Manager.

final credentials =
    await auth0.webAuthentication(useCredentialsManager: false).login();

Errors

The Credentials Manager will only throw CredentialsManagerException exceptions. You can find more information in the details property of the exception. Check the API documentation to learn more about the available CredentialsManagerException properties.

try {
  final credentials = await auth0.credentialsManager.credentials();
  // ...
} on CredentialsManagerException catch (e) {
  print(e);
}

Go up ⤴

🌐 Handling Credentials on the Web

This section describes handling credentials for the web platform. For mobile/desktop, see Credentials Manager.

The management and storage of credentials is handled internally by the underlying Auth0 SPA SDK, including refreshing the access token when it expires. The Flutter SDK provides an API for checking whether credentials are available, and the retrieval of those credentials.

Check for valid credentials

final isLoggedIn = await auth0Web.hasValidCredentials();

if (isLoggedIn) {
  // Retrieve the credentials and redirect to the main flow
} else {
  // No valid credentials exist, present the login page
}

Retrieve stored credentials

Credentials can be retrieved on application start using onLoad():

auth0Web.onLoad().then((final credentials) {
  if (credentials != null) {
    // logged in!
  }
});

They can also be retrieved at any time using credentials():

final credentials = await auth0Web.credentials();

Go up ⤴

📱 Authentication API

This feature is mobile/desktop only; the SPA SDK used by auth0_flutter does not include an API client.

The Authentication API exposes the AuthN/AuthZ functionality of Auth0, as well as the supported identity protocols like OpenID Connect, OAuth 2.0, and SAML. We recommend using Universal Login, but if you prefer to build your own UI you can use our API endpoints to do so. However, some Auth flows (grant types) are disabled by default so you must enable them on the settings page of your Auth0 application, as explained in Update Grant Types.

To log in or sign up with a username and password, the Password grant type needs to be enabled in your app. If you set the grants via the Management API you should activate both http://auth0.com/oauth/grant-type/password-realm and Password. Otherwise, the Auth0 Dashboard will take care of activating both when enabling Password.

💡 If your Auth0 account has the Bot Detection feature enabled, your requests might be flagged for verification. Check how to handle this scenario in the Bot Detection section.

⚠️ The ID tokens obtained from Web Auth login are automatically validated by auth0_flutter, ensuring their contents have not been tampered with. This is not the case for the ID tokens obtained from the Authentication API client, including the ones received when renewing the credentials using the refresh token. You must validate any ID tokens received from the Authentication API client before using the information they contain.

Login with database connection

final credentials = await auth0.api.login(
    usernameOrEmail: '[email protected]',
    password: 'secret-password',
    connectionOrRealm: 'Username-Password-Authentication');

// Store the credentials afterward
final didStore =
    await auth0.credentialsManager.storeCredentials(credentials);
Add an audience value

Specify an audience to obtain an access token that can be used to make authenticated requests to a backend. The audience value is the API Identifier of your Auth0 API, for example https://example.com/api.

final credentials = await auth0.api.login(
    usernameOrEmail: '[email protected]',
    password: 'secret-password',
    connectionOrRealm: 'Username-Password-Authentication',
    audience: 'YOUR_AUTH0_API_IDENTIFIER');
Add scope values

Specify scopes to request permission to access protected resources, like the user profile. The default scope values are openid, profile, email, and offline_access. Regardless of the values specified, openid is always included.

final credentials = await auth0.api.login(
    usernameOrEmail: '[email protected]',
    password: 'secret-password',
    connectionOrRealm: 'Username-Password-Authentication',
    scopes: {'profile', 'email', 'offline_access', 'read:todos'});

Sign up with database connection

final databaseUser = await auth0.api.signup(
    email: '[email protected]',
    password: 'secret-password',
    connection: 'Username-Password-Authentication',
    userMetadata: {'first_name': 'Jane', 'last_name': 'Smith'});

💡 You might want to log the user in after signup. See Login with database connection above for an example.

Passwordless Login

Passwordless is a two-step authentication flow that requires the Passwordless OTP grant to be enabled for your Auth0 application. Check our documentation for more information.

1. Start the passwordless flow

Request a code to be sent to the user's email or phone number. For email scenarios, a link can be sent in place of the code.

await auth0.api.startPasswordlessWithEmail(
    email: "[email protected]", passwordlessType: PasswordlessType.code);
Using PhoneNumber
await auth0.api.startPasswordlessWithPhoneNumber(
    phoneNumber: "123456789", passwordlessType: PasswordlessType.code);

2. Login with the received code

To complete the authentication, you must send back that code the user received along with the email or phone number used to start the flow.

final credentials = await auth0.api.loginWithEmailCode(
          email: "[email protected]", verificationCode: "000000");
Using SMS
final credentials = await auth0.api.loginWithSmsCode(
    phoneNumber: "123456789", verificationCode: "000000");

Note

Sending additional parameters is supported only on iOS at the moment.

Retrieve user information

Fetch the latest user information from the /userinfo endpoint.

This method will yield a UserProfile instance. Check the API documentation to learn more about its available properties.

final userProfile = await auth0.api.userInfo(accessToken: accessToken);

Renew credentials

Use a refresh token to renew the user's credentials. It's recommended that you read and understand the refresh token process beforehand.

final newCredentials =
    await auth0.api.renewCredentials(refreshToken: refreshToken);

// Store the credentials afterward
final didStore =
    await auth0.credentialsManager.storeCredentials(newCredentials);

💡 To obtain a refresh token, make sure your Auth0 application has the refresh token grant enabled. If you are also specifying an audience value, make sure that the corresponding Auth0 API has the Allow Offline Access setting enabled.

Errors

The Authentication API client will only throw ApiException exceptions. You can find more information in the details property of the exception. Check the API documentation to learn more about the available ApiException properties.

try {
  final credentials = await auth0.api.login(
      usernameOrEmail: email,
      password: password,
      connectionOrRealm: connection);
  // ...
} on ApiException catch (e) {
  print(e);
}

Go up ⤴

🌐📱 Organizations

Organizations is a set of features that provide better support for developers who build and maintain SaaS and Business-to-Business (B2B) applications.

💡 Organizations is currently only available to customers on our Enterprise and Startup subscription plans.

Log in to an organization

Mobile
final credentials = await auth0
    .webAuthentication()
    .login(organizationId: 'YOUR_AUTH0_ORGANIZATION_ID');
Web
await auth0Web.loginWithRedirect(
    redirectUrl: 'http://localhost:3000',
    organizationId: 'YOUR_AUTH0_ORGANIZATION_ID');

Accept user invitations

To accept organization invitations your app needs to support deep linking, as invitation links are HTTPS-only. Tapping on the invitation link should open your app.

When your app gets opened by an invitation link, grab the invitation URL and pass it to the login method.

Mobile
final credentials =
    await auth0.webAuthentication().login(invitationUrl: url);
Web
await auth0Web.loginWithRedirect(
    redirectUrl: 'http://localhost:3000',
    invitationUrl: url);

Go up ⤴

📱 Bot detection

This example is mobile/desktop only; the SPA SDK used by auth0_flutter does not include an API client.

If you are performing database login/signup via the Authentication API and would like to use the Bot Detection feature, you need to handle the isVerificationRequired error. It indicates that the request was flagged as suspicious and an additional verification step is necessary to log the user in. That verification step is web-based, so you need to use Web Auth to complete it.

try {
  final credentials = await auth0.api.login(
      usernameOrEmail: email,
      password: password,
      connectionOrRealm: connection,
      scopes: scopes);
  // ...
} on ApiException catch (e) {
  if (e.isVerificationRequired) {
    final credentials = await auth0.webAuthentication().login(
        scopes: scopes,
        useEphemeralSession: true, // Otherwise a session cookie will remain (iOS/macOS only)
        parameters: {
          'connection': connection,
          'login_hint': email // So the user doesn't have to type it again
        });
    // ...
  }
}

Go up ⤴