
Important Migration Notice: v2.0.0
auth0_flutter v2.0.0 is now Generally Available. This version includes updates to the underlying native Auth0 SDKs to support DPoP (Demonstrating Proof of Possession) and other improvements. See the Migration Guide for compatibility requirements and upgrade instructions.
Documentation
- Quickstarts: Native / Web - our interactive guide for quickly adding login, logout and user information to your app using Auth0
- Sample app - a full-fledged sample app integrated with Auth0
- API documentation - documentation auto-generated from the code comments that explains all the available features
- Examples - examples that demonstrate the different ways in which this SDK can be used
- FAQ - frequently asked questions about the SDK
- Docs Site - explore our Docs site and learn more about Auth0
Getting Started
Requirements
| Flutter | Android | iOS | macOS | Windows |
|---|---|---|---|---|
| SDK 3.24.0+ | Android API 21+ | iOS 14+ | macOS 11+ | Windows 10+ |
| Dart 3.5.0+ | Java 8+ | Swift 5.9+ | Swift 5.9+ | C++ 17, Visual Studio 2022 |
| Xcode 15.x / 16.x | Xcode 15.x / 16.x | vcpkg (for dependencies) |
Installation
Add auth0_flutter into your project:
flutter pub add auth0_flutter
Configure Auth0
📱 Mobile/macOS
Head to the Auth0 Dashboard and create a new Native application.
Using an existing Native application?
Select the Settings tab of your application's page and ensure that Application Type is set to Native. Avoid using other application types, as they have different configurations and may cause errors.
Scroll down and select the Show Advanced Settings link. Under Advanced Settings, select the OAuth tab and verify the following:
- Ensure that JsonWebToken Signature Algorithm is set to
RS256 - Ensure that OIDC Conformant is enabled
Finally, if you made any changes don't forget to scroll to the end and press the Save Changes button.
Configure the callback and logout URLs
The callback and logout URLs are the URLs that Auth0 invokes to redirect back to your app. Auth0 invokes the callback URL after authenticating the user, and the logout URL after removing the session cookie.
💡 On iOS 17.4+ and macOS 14.4+ it is possible to use Universal Links as callback and logout URLs. When enabled, auth0_flutter will fall back to using a custom URL scheme on older iOS / macOS versions.
Whenever possible, Auth0 recommends using Universal Links as a secure way to link directly to content within your iOS app. Custom URL schemes can be subject to client impersonation attacks.
This feature requires Xcode 15.3+ and a paid Apple Developer account.
Under the Application URIs section of the Settings page, configure the following URLs for your application for both Allowed Callback URLs and Allowed Logout URLs:
- Android:
SCHEME://YOUR_DOMAIN/android/YOUR_PACKAGE_NAME/callback - iOS:
https://YOUR_DOMAIN/ios/YOUR_BUNDLE_ID/callback,YOUR_BUNDLE_ID://YOUR_DOMAIN/ios/YOUR_BUNDLE_ID/callback - macOS:
https://YOUR_DOMAIN/macos/YOUR_BUNDLE_ID/callback,YOUR_BUNDLE_ID://YOUR_DOMAIN/macos/YOUR_BUNDLE_ID/callback - Windows:
YOUR_SCHEME://callback(direct, no server) orhttps://YOUR_HOSTED_DOMAIN/callback(intermediary server — see below)
Example
If your Auth0 domain was company.us.auth0.com and your package name (Android) or bundle ID (iOS/macOS) was com.company.myapp, then these values would be:
- Android:
https://company.us.auth0.com/android/com.company.myapp/callback - iOS:
https://company.us.auth0.com/ios/com.company.myapp/callback,com.company.myapp://company.us.auth0.com/ios/com.company.myapp/callback - macOS:
https://company.us.auth0.com/macos/com.company.myapp/callback,com.company.myapp://company.us.auth0.com/macos/com.company.myapp/callback - Windows (direct):
myapp://callback - Windows (intermediary server):
https://your-app.example.com/callback
💡 Windows: Always pass
appCustomURL— the custom-scheme URL your Windows app is registered to listen on (e.g.myapp://callback). Choose a scheme name unique to your application. You have two options for what to register in the Auth0 dashboard:
Direct (recommended for most apps): Pass only
appCustomURL. Register your custom scheme (e.g.myapp://callback) in the dashboard. Auth0 redirects straight to the custom scheme and the plugin picks it up immediately.Intermediary server (better browser UX): Also pass
redirectUrl(login) orreturnTo(logout) pointing to an HTTPS server you control. Register that HTTPS URL in the dashboard. Auth0 redirects to your server, which redirects onward to your custom scheme. This lets the server show a "Returning you to the app…" page and close cleanly, avoiding any hanging browser tab.
Take note of the client ID and domain values under the Basic Information section. You'll need these values in the next step.
Security Considerations for Custom URL Schemes
⚠️ Important Security Information
Custom URL schemes (nonverifiable callback URIs) can be vulnerable to app impersonation attacks, where malicious apps could potentially intercept OAuth authorization codes by registering the same custom scheme on a device.
Recommended Best Practices:
Use HTTPS-based schemes whenever possible:
- iOS 17.4+ / macOS 14.4+: Use Universal Links
- Android: Use Android App Links with HTTPS schemes
- These verifiable schemes cryptographically bind your app to your domain, preventing impersonation
If you must use custom URL schemes:
- Implement additional security measures such as PKCE (Proof Key for Code Exchange), which is automatically enabled in this SDK
- Consider using short-lived authorization codes
- Implement additional client-side validation
- Be aware that custom schemes offer no protection against malicious apps on the same device
For Windows applications: A custom URL scheme is required. Choose a scheme unique to your app (e.g.
myapp://). When using the direct pattern, PKCE (automatically enabled) is your primary protection. When using the intermediary server pattern, also ensure the server endpoint validates thestateparameter and uses HTTPS📖 For more details about app impersonation risks and mitigation strategies, see Auth0's Security Guidance: Measures Against App Impersonation
🌐 Web
Head to the Auth0 Dashboard and create a new Single Page application.
Using an existing Single Page application?
Select the Settings tab of your application's page and ensure that Application Type is set to Single Page Application.
Then, scroll down and select the Show Advanced Settings link. Under Advanced Settings, select the OAuth tab and verify the following:
- Ensure that JsonWebToken Signature Algorithm is set to
RS256 - Ensure that OIDC Conformant is enabled
If you made any changes don't forget to scroll to the end and press the Save Changes button.
Finally, head over to the Credentials tab and ensure that Authentication Methods is set to None.
Next, configure the following URLs for your application under the Application URIs section of the Settings page:
- Allowed Callback URLs:
http://localhost:3000 - Allowed Logout URLs:
http://localhost:3000 - Allowed Web Origins:
http://localhost:3000
💡 These URLs should reflect the origins that your app is running on. Allowed Callback URLs may also include a path, depending on where you're calling auth0_flutter's
onLoad()method –see below.
💡 Make sure to use port
3000when running your app:flutter run -d chrome --web-port 3000.
💡 Compile with WASM by running the app:
flutter run -d chrome --web-port 3000 --wasm.
Take note of the client ID and domain values under the Basic Information section. You'll need these values in the next step.
Configure the SDK
📱 Mobile/macOS/Windows
Start by importing auth0_flutter/auth0_flutter.dart.
import 'package:auth0_flutter/auth0_flutter.dart';
Then, instantiate the Auth0 class, providing your domain and client ID values from the previous step:
final auth0 = Auth0('YOUR_AUTH0_DOMAIN', 'YOUR_AUTH0_CLIENT_ID');
Android: Configure manifest placeholders
Open the android/app/build.gradle file and add the following manifest placeholders inside android > defaultConfig.
// android/build.gradle
android {
// ...
defaultConfig {
// ...
// Add the following line
manifestPlaceholders += [auth0Domain: "YOUR_AUTH0_DOMAIN", auth0Scheme: "https"]
}
// ...
}
Example
If your Auth0 domain was company.us.auth0.com, then the manifest placeholders line would be:
manifestPlaceholders = [auth0Domain: "company.us.auth0.com", auth0Scheme: "https"]
Not using web authentication?
If you don't plan to use web authentication, you will notice that the compiler will still prompt you to provide the manifestPlaceholders values, since the RedirectActivity included in this library will require them, and the Gradle tasks won't be able to run without them.
Re-declare the activity manually using tools:node="remove" in the android/src/main/AndroidManifest.xml file to make the manifest merger remove it from the final manifest file. Additionally, one more unused activity can be removed from the final APK by using the same process. A complete snippet to achieve this is:
<!-- android/src/main/AndroidManifest.xml -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.company.myapp">
<application android:theme="@style/AppTheme">
<!-- ... -->
<activity
android:name="com.auth0.android.provider.AuthenticationActivity"
tools:node="remove"/>
<!-- Optional: Remove RedirectActivity -->
<activity
android:name="com.auth0.android.provider.RedirectActivity"
tools:node="remove"/>
<!-- ... -->
</application>
</manifest>
💡
httpsschemes require enabling Android App Links. You can read more about setting this value in the Auth0.Android SDK README.
Whenever possible, Auth0 recommends using Android App Links as a secure way to link directly to content within your app. Custom URL schemes can be subject to client impersonation attacks.
💡 If your Android app is using product flavors, you might need to specify different manifest placeholders for each flavor.
Android: Biometric authentication
⚠️ On Android, your app's
MainActivity.ktfile must extendFlutterFragmentActivityinstead ofFlutterActivityfor biometric prompts to work.
iOS/macOS: Configure the associated domain
⚠️ This step requires a paid Apple Developer account. It is needed to use Universal Links as callback and logout URLs. Skip this step to use a custom URL scheme instead.
Select the Settings tab of your application's page, scroll to the end, and open Advanced Settings > Device Settings. In the iOS section, set Team ID to your Apple Team ID, and App ID to your app's bundle identifier.
This will add your app to your Auth0 tenant's apple-app-site-association file.
Next, open your app in Xcode by running open ios/Runner.xcworkspace (or open macos/Runner.xcworkspace for macOS). Go to the Signing and Capabilities tab of the Runner target settings, and press the + Capability button. Then select Associated Domains.
Under Associated Domains, add the following entry:
webcredentials:YOUR_AUTH0_DOMAIN
Example
If your Auth0 Domain were example.us.auth0.com, then this value would be:
webcredentials:example.us.auth0.com
If you have a custom domain, replace YOUR_AUTH0_DOMAIN with your custom domain.
⚠️ For the associated domain to work, your app must be signed with your team certificate even when building for the iOS simulator. Make sure you are using the Apple Team whose Team ID is configured in the Settings page of your application.
Windows: Configure protocol handler
⚠️ Runner integration required. The Windows authentication flow depends on callback plumbing that must be added to your app's runner (
windows/runner/main.cpp). The Flutter plugin itself does not automatically receive protocol-scheme activations from the OS — your runner must capture the custom-scheme callback URI and pass it to the plugin via thePLUGIN_STARTUP_URLenvironment variable. Copy the reference implementation from the example runner and adapt it to your ownwWinMain. Update the callback prefix constant to match your chosen scheme. The key pieces are:
- Single-instance mutex — ensures a second launch triggered by the OS protocol handler forwards its URI to the already-running instance rather than starting a new one.
- Pipe server — the already-running instance listens on a named pipe (
\\.\pipe\auth0flutter_pipe) for the URI forwarded by the second launch, validates it, and writes it toPLUGIN_STARTUP_URL.- Startup URI capture — on first launch the runner writes
argv[1](the protocol-scheme URI, if present) directly toPLUGIN_STARTUP_URLbefore Flutter starts.Without this integration,
login()will always time out withUSER_CANCELLEDon a standard consumer app because the callback never reaches the waiting plugin.
You have two options for how Auth0 delivers the callback to your app:
Option A — Direct custom-scheme redirect (recommended)
Register your custom scheme directly as the callback URL in your Auth0 dashboard:
- Allowed Callback URLs:
myapp://callback - Allowed Logout URLs:
myapp://callback
Pass appCustomURL (the custom scheme your app listens on). No redirectUrl is needed — appCustomURL is used as the redirect_uri automatically:
final credentials = await auth0.windowsWebAuthentication().login(
appCustomURL: 'myapp://callback',
);
Auth0 redirects straight to the custom scheme. The Windows OS hands the URL to your app and authentication completes immediately. The browser may leave a blank or protocol-handler tab open afterwards — this is a browser behaviour, not an error, and does not affect the login result.
Option B — Intermediary server redirect (better browser UX)
If leaving a blank tab open is unacceptable for your users, you can route the callback through a lightweight HTTPS server you control. The server receives the Auth0 redirect and immediately redirects onward to your custom scheme (e.g. myapp://callback), giving it the opportunity to show a clean "Returning you to the app…" page before the tab closes.
Register your server endpoint in the Auth0 dashboard:
- Allowed Callback URLs:
https://your-app.example.com/callback - Allowed Logout URLs:
https://your-app.example.com/logout
Pass both appCustomURL (what the app listens on) and redirectUrl (what Auth0 redirects to):
final credentials = await auth0.windowsWebAuthentication().login(
appCustomURL: 'myapp://callback',
redirectUrl: 'https://your-app.example.com/callback',
);
Minimal server implementation (Node.js/Express). Replace myapp with your chosen scheme:
app.get('/callback', (req, res) => {
const { code, state, error, error_description } = req.query;
if (error) {
res.redirect(`myapp://callback?error=${error}&error_description=${encodeURIComponent(error_description)}`);
} else {
res.redirect(`myapp://callback?code=${code}&state=${state}`);
}
});
⚠️ Validate the
stateparameter on your server before forwarding to your custom scheme to prevent open-redirect abuse. The SDK also validatesstateclient-side as part of PKCE, but defence-in-depth is recommended.
Both options use PKCE automatically — no additional configuration is required for security.
🌐 Web
Start by importing auth0_flutter/auth0_flutter_web.dart.
import 'package:auth0_flutter/auth0_flutter_web.dart';
Then, instantiate the Auth0Web class, providing your domain and client ID values from the previous step:
final auth0Web = Auth0Web('YOUR_AUTH0_DOMAIN', 'YOUR_AUTH0_CLIENT_ID');
⚠️ You should have only one instance of this class.
Finally, in your index.html add the following <script> tag:
<script src="https://cdn.auth0.com/js/auth0-spa-js/2.9/auth0-spa-js.production.js" defer></script>
Logging in
📱 Mobile/macOS
Present the Universal Login page in the onPressed callback of your Login button.
// Use a Universal Link callback URL on iOS 17.4+ / macOS 14.4+
// useHTTPS is ignored on Android
final credentials = await auth0.webAuthentication().login(useHTTPS: true);
// Access token -> credentials.accessToken
// User profile -> credentials.user
auth0_flutter automatically stores the user's credentials using the built-in Credentials Manager instance. You can access this instance through the credentialsManager property:
final credentials = await auth0.credentialsManager.credentials();
🪟 Windows
Windows uses windowsWebAuthentication(). appCustomURL is always required — it is the custom-scheme URL your Windows app listens on. redirectUrl is optional and only needed when using an intermediary HTTPS server (see Windows configuration above).
// Option A — direct custom-scheme redirect (simplest)
// appCustomURL is used as redirect_uri automatically
final credentials = await auth0.windowsWebAuthentication().login(
appCustomURL: 'myapp://callback',
);
// Option B — intermediary HTTPS server (cleaner browser UX)
// Auth0 redirects to redirectUrl; your server redirects on to appCustomURL
final credentials = await auth0.windowsWebAuthentication().login(
appCustomURL: 'myapp://callback',
redirectUrl: 'https://your-app.example.com/callback',
);
// Access token -> credentials.accessToken
// User profile -> credentials.user
Logging out also requires appCustomURL. returnTo is optional — if omitted, appCustomURL is used as the returnTo value in the Auth0 logout URL:
// Option A — direct custom-scheme redirect (simplest)
// appCustomURL is used as returnTo automatically
await auth0.windowsWebAuthentication().logout(
appCustomURL: 'myapp://callback',
);
// Option B — intermediary HTTPS server
// Auth0 redirects to returnTo; your server redirects on to appCustomURL
await auth0.windowsWebAuthentication().logout(
appCustomURL: 'myapp://callback',
returnTo: 'https://your-app.example.com/logout',
);
⚠️ Credentials are not automatically stored on Windows. You must manually store and manage the
credentialsobject returned fromlogin()(e.g., usingshared_preferencesor secure storage).
For other comprehensive examples, see the EXAMPLES.md document.
🌐 Web
Start by calling the onLoad() method in your app's initState().
@override
void initState() {
super.initState();
if (kIsWeb) {
auth0Web.onLoad().then((final credentials) => {
if (credentials != null) {
// Logged in!
// auth0_flutter automatically stores the user's credentials in the
// built-in cache.
//
// Access token -> credentials.accessToken
// User profile -> credentials.user
} else {
// Not logged in
}
});
}
}
Then, redirect to the Universal Login page in the onPressed callback of your Login button.
if (kIsWeb) {
await auth0Web.loginWithRedirect(redirectUrl: 'http://localhost:3000');
}
Using a popup
Instead of redirecting to the Universal Login page, you can open it in a popup window.
if (kIsWeb) {
final credentials = await auth0Web.loginWithPopup();
}
To provide your own popup window, create it using the window.open() HTML API and set popupWindow to the result.
You may want to do this if certain browsers (like Safari) block the popup by default; in this scenario, creating your own and passing it to loginWithPopup() may fix it.
final popup = window.open('', '', 'width=400,height=800');
final credentials = await auth0Web.loginWithPopup(popupWindow: popup);
⚠️ This requires that
dart:htmlbe imported into the plugin package, which may generate the warning 'avoid_web_libraries_in_flutter'.
💡 You need to import the
'flutter/foundation.dart'library to access thekIsWebconstant. If your app does not support other platforms, you can remove this condition.
For other comprehensive examples, see the EXAMPLES.md document.
Using DPoP (Demonstrating Proof of Possession)
Auth0 Flutter SDK supports DPoP (Demonstrating Proof of Possession), a security mechanism that cryptographically binds access tokens to your client, preventing token theft and replay attacks.
Quick Start:
// Mobile (Android/iOS)
final credentials = await auth0
.webAuthentication()
.login(useDPoP: true, useHTTPS: true);
// Web
final auth0Web = Auth0Web(
'YOUR_AUTH0_DOMAIN',
'YOUR_AUTH0_CLIENT_ID',
useDPoP: true,
);
Key Benefits:
- 🔒 Enhanced security through cryptographic token binding
- 🛡️ Protection against token theft and replay attacks
- 🌐 Full cross-platform support (Web, Android, iOS)
Platform Support:
| Feature | Web | iOS | Android |
|---|---|---|---|
| Login with DPoP | ✅ | ✅ | ✅ |
| CredentialsManager with DPoP | ✅ | ✅ | ✅ |
| Token Refresh with DPoP | ✅ | ✅ | ✅ |
Manual DPoP APIs (getDPoPHeaders(), clearDPoPKey()) |
✅ | ✅ | ✅ |
Note: In most cases, DPoP is managed automatically when
useDPoP: trueis enabled. Manual DPoP APIs are available for advanced use cases where you need direct control over DPoP proof generation.
📖 For complete DPoP documentation, examples, and troubleshooting, see DPOP.md
iOS SSO Alert Box

Check the FAQ for more information about the alert box that pops up by default when using web authentication on iOS.
💡 See also this blog post for a detailed overview of Single Sign-On (SSO) on iOS.
Common Tasks
📱 Mobile/macOS
- Check for stored credentials - check if the user is already logged in when your app starts up.
- Retrieve stored credentials - fetch the user's credentials from the storage, automatically renewing them if they have expired.
- Retrieve user information - fetch the latest user information from the
/userinfoendpoint. - Native to Web SSO - obtain a session transfer token to authenticate a WebView without re-prompting the user.
🪟 Windows
- Custom Protocol Handler: Windows uses a custom URL scheme that you choose (e.g.
myapp://). Auth0 can redirect to it directly (no server needed) or via an intermediary HTTPS server for a cleaner browser UX — see the Windows configuration section above - No Credentials Manager: Credential storage is not currently supported on Windows. Credentials must be managed manually in your app
- C++ SDK: The Windows implementation is built with native C++ using PKCE for secure authentication
- Unit Tests: Comprehensive unit tests for Windows OAuth helpers are available in
windows/test/
🌐 Web
- Handling credentials on the web - how to check and retrieve credentials on the web platform.
API reference
📱 Mobile/macOS/Windows
Web Authentication
💡 Windows: Always pass
appCustomURL— the custom-scheme URL your app listens on. PassredirectUrl(login) orreturnTo(logout) only when routing through an intermediary HTTPS server. See the Windows configuration section above for both options.
API
Credentials Manager
⚠️ Note: Credentials Manager is available on Mobile (Android/iOS) and macOS platforms only. Windows does not currently support credential storage. On Windows, you must manually manage credentials returned from
login().
🌐 Web
Feedback
Contributing
We appreciate feedback and contribution to this repo! Before you get started, please see the following:
Raise an issue
To provide feedback or report a bug, please raise an issue on our issue tracker.
Vulnerability Reporting
Please do not report security vulnerabilities on the public GitHub issue tracker. The Responsible Disclosure Program details the procedure for disclosing security issues.
Auth0 is an easy-to-implement, adaptable authentication and authorization platform. To learn more check out Why Auth0?
This project is licensed under the MIT license. See the LICENSE file for more info.