Update (December 6, 2018): Updated the client code to reflect the latest auth changes with AWS SDK for iOS (2.7.0+) and AWS Amplify. The embedded video goes through this blog in a step-by-step approach but it hasn’t been updated with the AWSMobileClient changes.

In my previous article, I talked about unauthenticated access to AWS for iOS. In that scenario, the mobile user never authenticates with username/password. Let’s recap three concepts to remember that carry over from the previous article.

1. Most AWS services require client requests be signed with AWS credentials (AWS Access key ID & Secret access key), not username & password.

2. Amazon Cognito Identity Pools (federated identities) is providing the unique identity Id (for the device, not really the user) and generates the required temporary, limited-privilege AWS credentials used by the AWS SDK to sign requests to AWS services.

3. The AWS Mobile SDK for iOS does all the work for the mobile developer when dealing with authentication tokens for retrieving, storing, and renewing AWS credentials using Amazon Cognito Identity Pool.

It may surprise you but the majority of mobile apps in the app store do not require users to authenticate before using their app.

Why force users to authenticate in the first place?

Well, there are many reasons. Fine-grain access control of your resources for each user, isolated cloud storage/settings for users with multiple devices, added security as user data is stored and accessed privately, and sharing of private content. On the flip-side, a developer may not care about the above and simply wants to collect personal information from the user such as email address, phone #, address, etc…when the user downloads their app and registers as a new user. The app developer can later use those collected attributes to engage and retain those app users through various channels such as SMS and email. Otherwise, if the user does not provide any registration or personal information, the user is anonymous, and there’s no other way to engage that user other than in-app messaging or push notifications.

Ways to authenticate your users

As a mobile developer, you have many options to support authentication. The most common is to offer basic username/password authentication with a user directory or provide authentication via 3rd party social network like Facebook, Google, or Twitter. For the social networks, the user authenticates with those services directly. I’ll be covering how to integrate auth using Facebook and Google in future articles.

What is basic authentication?

Basic authentication is when a user registers with an app or service by providing a unique username (can also be email or phone #) and associated password and the app uses those credentials in each signed request to a backend service.

Building basic authentication into your app

As the developer, when offering basic authentication, you must maintain a user directory service for those users, and securely store passwords and personal attributes (email, phone, etc…). In addition, you need a way for the user to reset his/her password and allow mechanisms to manage forgotten email/username and/or passwords. Fortunately, we have Amazon Cognito User Pools to manage all this for us and it can scale to millions of users. Never build your own user directory, it’s not worth it.

Introducing Amazon Cognito Users Pools

A user pool is a user directory in Amazon Cognito. With a user pool, your users can sign-up and sign-in using basic authentication, and all members of the user pool have a directory profile that you, as the developer, can access through the AWS SDK.

Cognito User pools provide:

Sign-up and sign-in services.

A built-in, customizable UI to sign-up and sign-in users (part of the mobile SDK)

Basic authentication, social sign-in with Facebook, Google, and Login with Amazon, as well as sign-in with SAML identity providers from your user pool.

User directory management and user profiles.

Security features such as multi-factor authentication (MFA), checks for compromised credentials, account takeover protection, and phone and email verification.

From basic authentication to AWS credentials

After successfully authenticating a User Pool user via username/password, Amazon Cognito User Pool issues JSON web tokens (JWT) that are exchanged for AWS credentials provided by an Amazon Cognito Identity Pool (or Cognito Federated Identities). Here’s what the flow looks like from basic authentication to access AWS resources. Note: As an iOS developer, you don’t need to ever worry about session tokens and/or JWT as the AWS SDK for iOS does all this for you. So, when you hear developers talking about passing around the JWT, they’re probably JavaScript developers :)

Remember, our mobile photo-sharing app is connecting to AWS backend resources, and to make requests to AWS, you must supply AWS credentials. Amazon Cognito User Pools for basic authentication and Amazon Cognito Identity Pools allow us to take traditional authentication methods and generate temporary AWS credentials for those authenticated mobile users to access your AWS resources.

Setting up email/password authentication using Cognito User Pools

In this section, we’ll be using the Amplify CLI to initialize and provision our AWS backend resources from a local Xcode project folder.

Install Amplify CLI

Before we get started, we are going to be using the AWS Amplify CLI which is part of the AWS Amplify Toolchain .

$ npm install -g @aws-amplify/cli $ amplify configure

This is a one-time install. Check out the Get Started tutorial for more details.

Initialize cloud backend from local project folder using Amplify CLI

From your local environment, create or use an existing Xcode iOS Swift project of your choice (Xcode 10 and Swift 4 is good) and then launch Mac Terminal in the root of your iOS project folder. Now, we’ll initialize our AWS backend project using the following Amplify command.

$ amplify init

You will be guided through the process of setting up the project. Make sure iOS is selected at the appropriate time.

By default, the following is created by the Amplify CLI after initializing on your behalf:

1. An empty Unauthenticated IAM Role with no permissions set

2. An empty Authenticated IAM Role with no permissions set

Next, let’s add authenticated access to our mobile project. We’ll follow the same process as outlined in the Email & Password option tab in the AWS Documentation.

$ amplify add auth

Return through the default configuration.

The default configuration for “amplify add auth” is creating a Cognito User Pool and Cognito Identity Pool with opinionated “default” configuration settings. If you opt for setting up your own auth configuration, select No and walk through the various options like MFA, verification codes, SMS, password length, etc… The non-default option is not covered in this article but feel free to play around with the many configuration options.

Push the local configuration changes to your AWS account

$ amplify push

With this feature “amplify add auth” integrated into our Xcode project, the Amplify CLI staged a local Amazon CloudFormation template and deployed it to your AWS account as a CloudFormation Stack that provisions the following AWS resources on your account:

· A new Cognito Identity Pool in your AWS account and associates the pool with the existing projects authenticated and unauthenticated IAM roles.

· A new Cognito User Pool in your AWS account and associates this user pool with the above Identity Pool to be used for temporary AWS credentials.

· A new awsconfiguration.json file with references to your newly created Cognito Identity Pool via the “CredentialsProvider” and Cognito User Pools via “CognitoUserPool” setting.

Note: At this point, the authenticated and unauthenticated IAM roles still do not have any access policies associated, so there are no AWS resources that your app users can access in your AWS account even if they registered and provided basic authentication via username and password to the Cognito User Pool.