Flutter + AWS Amplify — Part 2: Authentication

Having been distracted for a while, I’m back to resume this series on AWS Amplify with Flutter.

In this article, we are going to explore and setup AWS Amplify Authentication for the To-do app we created in the previous article.

If, like me, you are also getting back to Part 2 after a long time or you are starting afresh from Part 2, I would highly recommend downloading the Part1 code from the Git repository here. I have made a few changes for it to be null-safety compliant and compatible with Flutter 2.5.

You can checkout the first part by clicking here.

Let’s dive right in ..

Authentication:

Having used Firebase Authentications for all my projects in the past, I am fairly aware of the Cloud based Authentication systems and what they have to offer. AWS Amplify, like all the other providers, gives you a plethora of options to select from, such as email and password, Amazon, Google, Facebook, and Apple.

It then goes a step further and provides you the option to integrate Multi-factor Authentication (MFA) to your app — which could come in handy if you are developing apps for the military to launch ICBMs, maybe. It’s exactly like how you logon to amazon website from a new browser — first you login using username and password, then Amazon sends you a verification code to the registered mobile number for you to enter, only after which you are let in.

Personally, I have moved on to password-less authentication a while back since it’s a lot easier from end user’s point of view and most of my clients too prefer the same (mobile number + verification code based authentication). But for this article, to keep things simple, we’ll continue to use email and password authentication, without any complications of MFA.

Setup:

In your case ‘Email’ might have been pre-selected, but I removed it to show the above error. Either one of email, phone number or username has to be selected as the preferred login method.

The Authentication screen has 2 panels, one for configuring Sign-in, the other for configuring sign-up.

How it works:

  • ‘Email’, ‘username’ & ‘phone number’ login mechanisms will go with a password.
  • However, you may also use — ‘Google’, ‘Facebook’, ‘Amazon’ and ‘Apple ID’, for which you’ll need to do the configurations using the ‘App ID’, ‘App Secret’ (which you’ll get from the relevant developer portals) and a redirect URL.

Let’s select ‘Email’ from the ‘login mechanism’ dropdown:

And the screen then looks like below. ‘Email’ selected for login as well as the Sign up settings:

Next, inside the ‘Configure sign up’ section, click on the Add attribute dropdown to select the additional data you want to collect from the user at the time of signup — Name’ and ‘Phone Number’.

And finally, you can setup your password rules by clicking on ‘Password protection settings’.

Let’s remove all the password checks and bring down the character length to 6 to keep things simple.

Click ‘Deploy’ at the bottom of the screen and then ‘Confirm Deployment’, to finalize and apply the signup and login mechanisms.

And the Marriage (Again!)

It is time to implement AWS Amplify Authentication inside our To-do app. But first, let’s get the sign up and sign in UIs going.

Inside of our To-do app, I created a simple Sign In and Sign Up pages like below:

Now, when a new user signs up, Amplify expects one additional step — Account Verification : A verification code (OTP) is sent to the user either via SMS or email, depending on how you set it up in the previous step, after setting up the Password rules (within the Password protection settings).

I know the title says ‘Forgot password …’, but the same template is used for Account Verification step as well.

Let’s change the Subject and Body from default values to the values in the screenshot above and save changes.

And now, let’s design a screen for Account Verification step. Code below:

Before proceeding further let’s add the Amplify Auth plugin to pubspec.yaml file: amplify_auth_cognito: ^0.2.4

(https://pub.dev/packages/amplify_auth_cognito — to get the latest version)

Then, let’s add the AmplifyAuthCognito plugin to the Amplify configuration and while we are at it, let’s move that configuration part alone from the home.dart to main.dart. The main.dart file should now look like below:

Let’s summarize what we’ve done so far — we’ve setup the Amplify Authentication backend from Admin UI, designed the UI for SignIn, SignUp and Account Verification pages and have added the Amplify Auth plugin to the app.

Now, comes the tricky bit. Let’s first see what we want to achieve, so we have a clear roadmap of where we wanna go:

  1. SignUp page needs to be hooked up to the Amplify Auth backend.
  2. On successful SignUp, user should be re-directed to Account Verification page.
  3. After successful account verification, user should be re-directed to SignIn page.
  4. On successful sign in, user should reach the homepage.
  5. Signout, should end the session and take the user to login page.

Before proceeding, to keep things clean, let’s create a new file called ‘auth.dart’ inside /lib folder. This is where all the backend code will reside — similar to how we split the DB backend part to ‘DB.dart’.

Add the below code to create a placeholder for all the authentication related code:

Step 1 — Sign Up:

As you can see, we are username, email, password and phone number to AuthServices. The email and password are used as auth credentials, while username and phone number will be added to the user account as user attributes. Let’s see that code now.

In the auth.dart file, add the below code for signup:

Here, we are creating a Map called attributes where the phone number and name is stored. Then we pass this attributes map along with the email and password, to the signup code.

Step 2 — Account Verification

Let’s run the code and see it in action …

After you register, the app should show you the Verification page like below:

Let’s logon to the AWS Amplify Admin Panel and check if the signup was successful.

You should see an entry like below, when you click on User Management inside the Admin Panel. The status is UNCONFIRMED as the verification step is still pending from the app.

Before we head-over to complete the code for the verification screen, let’s explore User Management a little.

Clicking on the username/ email will take you to the User Profile page. Under User info, you will notice that the attributes we passed during signup have been added successfully.

You can also manually Confirm, Suspend, Delete account and Reset Password from this screen.

Brilliant, now let’s head-over and complete the code for Verification. Inside auth.dart let’s add the below code:

With this, we are redirecting the user to the SignIn page after successful verification.

Next, open accConf.dart file and connect it to the code we wrote in the previous step, using the below code to the onPressed event:

await AuthServices().confUser(widget.email, verCode, context);

Save all the files and enter the verification code in the app on your emulator. It should take you over to the SignIn page, once the verification is successfully complete.

Steps 3 and 4 — SignIn page:

If you notice, I have used a provider in the auth.dart file right after signin. This provider along with a changenotifier, will help us know if the user is signed in or not. Let’s finish setting up the provider.

Add this plugin to pubspec file: provider: ^6.0.1

(https://pub.dev/packages/provider for latest version).

Add a provider.dart file under the /lib folder and add the below code to it:

Whenever there is an Auth change event, we can call changeUserStatus() and update the status to true or false based on auth status. Then the notifyListener() will notify whoever is listening about the auth status change.

Let’s update the main.dart file to look like below:

In the above gist, I have initialized the provider by wrapping MyApp inside a changenotifiedprovider.

Then I check the login status by calling the getAuthStatus() right after Amplify.configure. This will check if the user is logged in, if yes — update the provider we created earlier to true, by calling changeUserStatus; if no — then user will be redirected to the login page.

And finally, inside the build widget, we call the provider to check the login state and hence listen for any auth state change. If there is any auth state change, the notifier inside the provider.dart file will notify the build widget.

The only other things left to do is, redirect the user based on auth status. So we modify ‘home:’ inside MaterialApp in such a way that when Amplify Configuration is in progress or Auth Status Check is in progress we show a loading page to the user. Later, when these are complete, we check the loginstate, if true (user logged in), we send the user to the homepage, else we show the login page.

Step 5— Sign out:

And just like that, we have successfully added AWS Amplify Authentication to our To-do flutter app.

Run the app on the emulator and sign in to the app using the newly added auth method.

The completed code for this article is available in the git repo:

Select the ToDo-App-Part2 branch.

Wait, there is more — you can read more about Amplify Authentication at the official site here.

Also, if you are not familiar with Providers and how to use them (they are fairly easy to understand and come in very handy while building complex apps), you should look that up too. For this article, I used a simple Provider, but you are free to explore other options as well, whichever suits you best.

Alright, let me know if there are any mistakes or if you need any more details and I’d be glad to see some feedback.

Next time, more on Authentication and Data manipulation. See you soon!