Front-End Web & Mobile

Authentication with AWS Amplify Flutter for Mobile, Web, and Desktop

Today the Amplify Flutter team has released a new developer preview version for the Authentication category re-write completely in Dart, which expands support for Flutter application’s target platform to web and desktop. AWS Amplify Flutter had its initial Developer Preview release on August 2020. With that release Amplify Flutter provided a set of tools and services for building secure, scalable Flutter applications targeting iOS and Android. Since then, the Amplify Flutter team kept improving, stabilizing and extending the functionality of the Amplify Flutter library. The two highest requested feature requests for Amplify Flutter are expanding support to Flutter for web and desktop. Due to this the high demand from our customers, ensuring all our remaining Amplify categories support Flutter for web and desktop is our highest priority!

In this blog post you will learn to use AWS Amplify Authentication and the Authenticator UI libraries on all supported platforms.

Cross platform GIF

Requirements

  • A Flutter application targeting Flutter SDK >= 3.0.0 with AWS Amplify configured
    • For creating an AWS Account and setting up AWS Amplify CLI, you can follow this documentation
    • For creating a Flutter project and configuring a Flutter application, you can follow this documentation

Depending on the target, you need to following as well:

  • For iOS
    • at least iOS 13.0 and XCode version >=13.2
  • For Android
    • at least Android API level 24 (Android 7.0) or above
  • For web any of the following browsers
    • Chrome (mobile & desktop)
    • Safari (mobile & desktop)
    • Edge (mobile & desktop)
    • Firefox (mobile & desktop)
  • For Windows
    • Visual Studio 2022 When installing Visual Studio, select the “Desktop development with C++” workload, including all of its default components, to install the necessary C++ toolchain and Windows SDK header files.
  • For Linux
  • For macOS
    • XCode version >=13.2

Setting Up the Target Platform

Each target platform might require some preparation upfront. Below are the steps needed to setup your target platforms.

macOS

For macOS you need to enable code signing and add your app to at least one app group. You can do that by:

  • Open the macOS folder from your project in Xcode (from IDE, right click on the macos folder and select “Open in Xcode”)
  • Click “Runner” and then “Signing & Capabilities”

MacOS Setup

  • Click the “+” icon and search for “Keychain”. Add the “Keychain Sharing” capability.
  • Scroll down to Keychain Sharing in the original window, and click the “+” icon. By default, your bundle ID will be used. No need to change that or add any others unless you want to test sharing credentials across multiple apps.

keychain groups

  • macOS needs you to request a specific entitlement in order to access the network. You can either do that on the Signing and Capabilities screen:

Signing and capabilities

  • or open macos/Runner/DebugProfile.entitlements and ReleaseProfile.entitlements and add the following key-value pair.
    • <key>com.apple.security.network.client</key>
      <true/>

Please add a development team and enable signing for your project if you have not already

Linux

  • Install the following libraries:
    • libsecret-1-dev
    • libglib2.0-dev

Getting Started

As of Flutter 3.0, when you create a Flutter application, it will enable the support for Web and Desktop for the host platforms that you are in.

If you want to support Desktop for an ongoing project you can use the following command:

flutter create –platforms=windows,macos,linux .

You can check if your Desktop support is enabled or not by running the flutter devices:

msalihg@ ~ % flutter devices
2 connected devices:
macOS (desktop) • macos • darwin-arm64 • macOS 12.4 21F79 darwin-arm
Chrome (web) • chrome • web-javascript • Google Chrome 103.0.5060.134

Once you see the Desktop platform that you are in, it means you are good to go! For testing it out, run your current project and you should see the infamous Flutter counter application:

Chrome Authenticator main page

Now that you have your application running, it is time to configure auth for your project using the Amplify CLI in your terminal:

msalihg@ dart_first_amplify_authentication % amplify add auth
Using service: Cognito, provided by: awscloudformation
 
 The current configured provider is Amazon Cognito. 
 
 Do you want to use the default authentication and security configuration? Defau lt configuration
 Warning: you will not be able to edit these selections. 
 How do you want users to be able to sign in? Username
 Do you want to configure advanced settings? No, I am done.
✅ Successfully added auth resource dartfirstamplifyautha94862bb locally

✅ Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud

msalihg@ dart_first_amplify_authentication % amplify push 
⠸ Fetching updates to backend environment: dev from the cloud.⠋ Building resourc✔ Successfully pulled backend environment dev from the cloud.

    Current Environment: dev
    
┌──────────┬──────────────────────────────┬───────────┬───────────────────┐
│ Category │ Resource name                │ Operation │ Provider plugin   │
├──────────┼──────────────────────────────┼───────────┼───────────────────┤
│ Auth     │ dartfirstamplifyautha94862bb │ Create    │ awscloudformation │
└──────────┴──────────────────────────────┴───────────┴───────────────────┘
? Are you sure you want to continue? Yes
⠧ Updating resources in the cloud. This may take a few minutes...
...
✔ All resources are updated in the cloud

The amplify add auth CLI command will add authentication properties to your project, you can pick any way of authentication that suits your needs while configuring. You can pick username, email, phone, social authentications and many more! amplify push will push the settings to the cloud.

After that, you can start adding amplify libraries to your project to use these configurations:

Implementing the Code

For adding the libraries, open the pubspec.yaml file. Paste the added lines below under the dependencies tag.

dependencies: 
    flutter:
      sdk: flutter
       amplify_auth_cognito: ^1.0.0-0
       amplify_authenticator: ^1.0.0-0
       amplify_flutter: ^1.0.0-0
  • amplify_auth_cognito: The Amplify Auth category provides an interface for authenticating a user. Behind the scenes, it provides the necessary authorization to the other Amplify categories. It comes with default, built-in support for Amazon Cognito User Pool and Identity Pool.
  • amplify_authenticator: Authenticator component adds complete authentication flows to your application with minimal boilerplate.
  • amplify_flutter: Library to help you configure Flutter and Amplify with helper methods.

After you add the libraries, run flutter pub get command.

You will continue by adding the Amplify Authenticator and Amplify Authentication libraries to your code. Amplify Authentication provides an interface for authenticating a user. Behind the scenes, it provides the necessary authorization to the other Amplify categories. Amplify Authenticator UI library encapsulates an authentication workflow and is backed by the cloud resources set up in your Auth cloud resources.

import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_authenticator/amplify_authenticator.dart';
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:flutter/material.dart';

import 'amplifyconfiguration.dart';

Future<void> main() async {
 WidgetsFlutterBinding.ensureInitialized()*;*
 await _configureAmplify();

  runApp(const DartFirstAmplifyAuthenticationApp());
}

Future<void> _configureAmplify() async {
  try {
    final authPlugin = AmplifyAuthCognito();
    await Amplify.addPlugin(authPlugin);

    await Amplify.configure(amplifyconfig);
  } on Exception catch (e) {
    safePrint('An error occurred while configuring Amplify: $e');
  }
}

class DartFirstAmplifyAuthenticationApp extends StatelessWidget {
  const DartFirstAmplifyAuthenticationApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Authenticator(
      child: MaterialApp(
        builder: Authenticator.builder(),
        title: 'Amplify Dart First Authentication Demo',
        home: const MyHomePage(title: 'Amplify Dart First Authentication Demo'),
      ),
    );
  }
}

If you run your application now, you should see the following:

Chrome (Web)

Chrome Authenticator

macOS (Desktop)

Macos desktop corrected

Windows (Desktop)

Windows Authenticator

The Authenticator UI component gives you a fully functional authentication flow for your application. It gets the proper setup and rules from the authentication configuration that you have decided earlier.

Go ahead and test out user creation flow:

Chrome Authenticator 1

If you click on Create Account button, it will take you to a account confirmation page which also comes out of the box for you!

Chrome Authenticator verification

Once you confirm your account, it will take you to the MyHomePage widget:

Chrome Authenticator main page

Instead of the counter, you can add a sign out button and show some information about current user.

class _MyHomePageState extends State<MyHomePage> {
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
          Padding(
          padding: const EdgeInsets.only(bottom: 8),
             child: FutureBuilder<AuthUser>(
               future: Amplify.Auth.getCurrentUser(),
               builder: (context, currentUserSnapshot) {
                 if (currentUserSnapshot.connectionState ==
                     ConnectionState.active) {
                   return const Text('Loading user');
                 } else {
                   return Text(
                     'Welcome to $_osPlatform ${currentUserSnapshot.data?.username}',
                   );
                 }
               },
             ),
           ),
           const SignOutButton(),
          ],
        ),
      ),
    );
  }

   // Returns a name to the current platform
   String get _osPlatform {
     if (kIsWeb) {
       return 'Web';
     } else if (Platform.isAndroid) {
       return 'Android';
     } else if (Platform.isIOS) {
       return 'iOS';
     } else if (Platform.isMacOS) {
       return 'macOS Desktop';
     } else if (Platform.isWindows) {
       return 'Windows Desktop';
     } else if (Platform.isLinux) {
       return 'Linux Desktop';
     } else {
       return 'Unknown';
     }
   }
}

At the above code, you have removed everything related to the counter (FloatingActionButton, Text widgets inside the Column widget and all the variables and functions related to the counter). Now you have a widget to fetch the current user information and a SignOutButton instead. That is a special button from Authenticator library to sign the current user out easily.

Now if you run your application one more time. You will see the following:

Homepage after login

Conclusion

Amplify’s update on its Authentication and Authenticator libraries will give developers a chance to expand their authentication flow support to Web and Desktop. That is why you can have a fully functional authentication flow with minimum effort and all of the components that you see with Authenticator is customizable. Also, if you wish to not use the Authenticator library, you can hook the authentication flow to your own UI components as well. Check out the Amplify documentation for more information about it. You can check out to the source code from here Now it is time to go ahead and try out these libraries, give us feedback over GitHub or Discord.

We will be expanding support to Flutter for web and desktop for other categories on a rolling basis starting with the API category. Please use this RFC to provide us with feedback.

Salih Guler

Muhammed Salih Güler

Muhammed Salih Güler is a Senior Developer Advocate at AWS Amplify. He helps Flutter developers’ by improving their learning experiences of Flutter and Amplify by creating content, giving talks and answering questions.

Abdallah Shaban

Abdallah Shaban

Abdallah Shaban is a Senior Product Manager at AWS Amplify, helping Javascript and Flutter developers create apps that delight their users. When not working, Abdallah tries to keep himself updated on the newest innovations in tech, playing his guitar, and traveling.

Ashish Nanda

Ashish Nanda

Ashish Nanda is a Senior Software Engineer and Tech Lead at AWS Amplify. He leads design and engineering on the JavaScript and Flutter open source SDK teams with the goal of helping developers build full-stack web and mobile applications quickly & seamlessly using cloud services.