How to use Corbado to build a Flutter app using passkey authentication

How to use Corbado to build a Flutter app using passkey authentication

The following article describes how you can use Corbado's authentication package for Flutter to effortlessly offer your users passkeys. The package comes with passkey-first authentication as well as complete session and user management solution.

Hello Flutter developers,

In our last tutorial, we introduced the open-source Flutter passkeys package that allows an easy and flexible integration of passkeys into your Flutter app with any passkey backend provider.

To go one step further, we now want to showcase how you can build a Flutter app with a fully passkey-centered authentication and user management solution (not just the passkey login itself). This solution comes in the form of the corbado_auth package. Besides the pure passkey login and sign-up functionality (which are offered by the passkeys package already), the corbado_auth package currently comes with the following additional features:

  • Session management
  • Email magic link as fallback and double opt-in

Setting up passkeys on your own is still a struggle, but also taking care of these additional features on your own requires a lot of developer resources if done properly, so we want to take that burden for you and let you focus on your core features of your Flutter app.

The corbado_auth package together with Corbado’s service is a full authentication SDK that covers all aspects of user management and authentication for you (e.g.,recovery, fallbacks, etc.). The corbado_auth package currently supports Android and iOS (more platforms to come).

You can use the package as well as Corbado completely for free, as this is another step in our journey to make the Internet a safer place.

The main goals of the corbado_auth Flutter package are:  

  • Simplicity: Build an easy-to-use Flutter passkey package that enables every Flutter developer to implement passkey-based authentication with little effort.
  • Holistic: All aspects are covered, so you can tick user management and authentication for your app.
  • Support: There are a few pitfalls when setting up authentication. We try to provide guidance and help for common mistakes.

This tutorial is structured as follows:

1. The corbado_auth package

2. Configure Corbado project

      2.1. Add Android app

      2.2. Add iOS app

3. Create flutter application

      3.1. Authentication logic

      3.2. Login and Content activity

4. (Optional) Bind passkeys to specific domain

5. Run the example app

6. Troubleshooting

      6.1. Weak SHA-1 algorithm for Android keystore

      6.2. Android screen lock not set up on virtual Android device

7. Conclusion

The code of this tutorial is taken from our corbado_auth integration example, which you can find here.

Here’s a preview of the running example app in Android:

1. The corbado_auth package

To better understand the architecture of the corbado_auth package, we look at the relationship of the corbado_auth package and the passkeys package.

corbado_auth is Corbado’s full-fledged authentication SDK which utilizes the passkeys package for passkey authentication. While any passkey backend can theoretically be plugged into the passkeys package, the corbado_auth package plugs in Corbado's passkeys backend, so no additional infrastructure is needed.

For a more detailed overview of the passkeys package, and further elaboration on the role of passkey backend providers, please have a look at the overview of the first Flutter blog post.

2. Configure Corbado project

Go to the Corbado developer panel and create a new account and project. After successful sign up, in the wizard, select ‘Integration guide’, ‘Native / Flutter app’ and ‘No existing users’.

Note: Please make sure that under Settings -> User interface -> Identity verification "Option 2: No verification required" is selected. This should be set by default, when selecting “Native / Flutter app” in the previous step.

Now, some platform-specific settings have to be made. Navigate to the Native Apps settings and add a new Android / iOS app as shown in the next steps.

2.1. Add Android app

Set up an Android app by clicking "Add new". You will need your package name (e.g. com.corbado.passkeys.example) and your SHA-256 fingerprint (e.g.54:4C:94:2C:E9:...).

The package name of your app is defined in /android/app/build.gradle (applicationId). Its default value for the example app is com.corbado.passkeys.example.

Add Android App

You can obtain the SHA-256 fingerprint of your debug signing certificate by executing the following command:

macOS / Linux:

keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android


keytool -list -v -keystore "\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android

If you encounter any issues, please have a look Troubleshooting.

2.2. Add iOS app

2.2.1. Create an iOS app and configure the example in XCode

We need to establish trust between your iOS app and the relying party server. Your app will be identified through your Application Identifier Prefix (e.g. 9RF9KY77B2) and your Bundle Identifier (e.g. com.corbado.passkeys). You need an Apple developer account to set up both. If you haven't got one yet, set up a new account.

Note: When creating your Bundle Identifier, make sure that the "Associated Domains" capability is enabled.

Bundle ID

The Application Identifier Prefix can be obtained by going to your Apple Developer Certificates, Identifier & Profiles associated with your Apple Developer account.

Open the example in Xcode now by opening /packages/passkeys/passkeys/example/ios. In "Runner -> Signing & Capabilities" enter your Application Identifier Prefix and your Bundle Identifier.

2.2.2. Set up iOS Application Identifier Prefix and Bundle Identifier

Set up an iOS app by clicking "Add New". You will need your Application Identifier Prefix and your Bundle Identifier that we set up in step 2.2.1.

Add iOS App

Afterwards, the Corbado relying party server will host an apple-app-site-association file at https://{ CORBADO_PROJECT_ID }} This file will by downloaded by iOS when you install your app. To tell iOS where to look for the file, we need the next step in our setup.

2.2.3. Configure your iOS project

In your Xcode workspace, you need to configure the following settings: In "Signing & Capabilities" tab, add the "Associated Domains" capability and add the following domain: webcredentials:{CORBADO_PROJECT_ID} Now, iOS knows where to download the apple-app-site-association file from.

If you forget about this step, the example will show you an error message like “Your app is not associated with your relying party server. You have to add...”.

Your configuration inside Xcode should look similar to what is shown in the screenshot below (you will have your own Corbado project ID and a different Bundle Identifier).

Apple Signing Capabilities

3. Create Flutter application

In the following, we explain step-by-step how to implement a basic Flutter app. If you want to see the final version of the example, please check the GitHub repo.

We start byinitiating our project with „flutter create passkeys-demo-flutter“. Under lib/main.dart we will find the default flutter widget.

We will add the following packages

  • corbado_auth for authentication
  • passkeys for better error handling (corbado_auth uses passkeys under the hood so we can use Exception types from the passkeys package for better error handling)
  • get_it for singleton handling.
  • rxdart for using BehaviourSubjects
  • oktoast for showing error messages to the user

You can add them all at once by executing

flutter pub add corbado_auth passkeys get_it rxdart oktoast

3.1. Authentication logic

Next, we’ll create a folder named “services” which contains all business logic. In there, we create a file called app_locator.dart, which we will use to register our singletons with the get_it package.

Passkeys Flutter

The only singleton we got for now, is an instance of CorbadoAuth.dart, the main interface of the corbado_auth package. To initiate CorbadoAuth, we need the Corbado project ID from step 2. When running our app we’ll register it as an environment variable, so we’ll take it from there.

Now that CorbadoAuth is easily available everywhere via GetIt, we create a service which handles all means of authentication for our app and provides the UI with a user object if someone is logged in. For this, we create a file auth_service.dart containing our AuthService class. This class uses the CorbadoAuth instance we registered previously.

Passkeys Flutter

To make it easy for our widgets to access our AuthService, we register it as a singleton in app_locator.dart as well. The UI will use the AuthService for all authentication related tasks. The updated app_locator.dart file looks like this:

3.2. Login and content activity

That’s it concerning the authentication business logic of our application. We can now focus on the UI. First, inside a “components”-folder, let’s create a custom button for our UI to prevent redundant code in our screens:

Passkeys Flutter

Our app will have two screens: one for authentication and one for logged-in users. We’ll therefore create two files named login_activity.dart and content_activity.dart:

Passkeys Flutter

The login activity will be launched on startup while the content activity will be displayed once a user has authenticated. The login activity offers a text input for the username, as well as a sign up and login button. When clicked, the login activity performs the respective action via our AuthService. If an error occurs, the oktoast package is used to display a toast containing the error message to the user. If the authentication succeeded, the user is directed to the content page.

Now to the final widget: the content activity. As seen in the code snippet above, once authentication succeeds, the ContentActivity is launched. We already created a file for this class: activities/content_activity.dart. Inside of this file, we now create the ContentActivity class which gets accessed by the LoginActivity. It just displays a little bit of text containing the username as well as a logout button.

Finally, we can swap out our main.dart content for the following snippet which directs us to our login activity, when we start the app:

So, when we run the app, we have to add the Corbado project ID as an environment variable like this:

flutter run –dart-define=CORBADO_PROJECT_ID=pro-xxx

Then, you should be able to sign up and login with an email of your choice. Our example on GitHub only varies slightly, as we’ve kept the design and theme customizations in this tutorial to a minimum to keep the amount of code small.

Flutter passkeys running app

4. (Optional) Bind passkeys to specific domain

Each passkey is bound to a certain domain, the so-called relying party ID. If you use the Corbado default settings, passkeys are bound to your project-specific Corbado subdomain at https://<Corbado project ID>

Of course, you can also use your own domain for passkey binding. To do so, you need to verify that both the native app and domain belong to you. Therefore, you need to host a configuration file on your domain. For Corbado default settings, you can find these files here (it can take up to 5 minutes after you added the native app information in the Corbado developer panel until the files are deployed):

  • Android: assetlinks.json at
  • iOS: apple-app-site-association at

To create these files on your own, you can copy the file structure from the project-specifc Corbado subomains above. Then, you need to update the respective relying party ID / specific domain in the file.

In the case of Android, for the assetlinks.json file, you can also use Android Studio’s Digital Asset Links File Generator to generate the file. You find it under “Tools > App Links Assistant > Open Digital Asset Links File Generator“ in Android Studio.

Passkey Android App Linking Assistant
Passkey Android App Linking Assistant
Passkey Android App Linking Assistant

If you’re using Corbado as passkey infrastructure provider, but want to bind the passkey to a specific domain (other than the default one), you need to make sure to also adapt the relying party ID in the Corbado developer panel under “Settings > General > URLs” to be the same as your newly selected, specific domain.

5. Run the example app

Make sure that you have a running virtual device or a physical device connected to your machine.

Now, you are fully set and you can start signing up with your first passkey in the example by running the following command:

flutter run –dart-define=CORBADO_PROJECT_ID=<your-corbado-project-id> lib/main.dart

If you run the example from your IDE, please make sure to either:

  • set the CORBADO_PROJECT_ID environment variable to your Corbado project ID
  • replace const String.fromEnvironment ('CORBADO_PROJECT_ID') directly in the example with your Corbado project ID

6. Troubleshooting

6.1 Weak SHA-1 algorithm for Android keystore

If you’ve executed one of the commands in step 2.1.1 to view your SHA-256 fingerprint and you see an error message like the following “SHA1withRSA (weak)”:


Then, you need to create a new Android keystore with a stronger algorithm. You can do so with one of the following commands:

  • macOS / Linux:
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
  • Windows:
keytool -list -v -keystore "\.android\debug.keystore”-alias androiddebugkey -storepass android -keypass android

6.2 Android screen lock not set up on virtual Android device

If you run the application in a virtual Android device, and it says that you can't create a passkey, you have to properly set up a screen lock or biometrics on the device. To do so, open the settings, search for security settings and add a PIN as well as a fingerprint as shown below (PIN is required for fingerprint):

Flutter Passkey Troubleshooting Android

7. Conclusion

Congrats! You have successfully set up your authentication and user management for your Flutter app with Corbado leveraging the corbado_auth package.

Besides the current focus on passkeys as authentication method, we plan to add more features to the corbado_auth package that can help for more complex apps. Examples of these feature are:

  • Support for existing users
  • Native email magic links / OTP as fallback (when an existing user has not set up a passkey yet)
  • Cross-sync passkeys with a web app
  • Advanced passkey management features for different cloud backup systems (e.g. support ofGoogle Password Manager and iCloud Keychain for the same user)

Enjoyed this read?

Stay up to date with the latest news, strategies and insights about passkeys sent straight to your inbox!