AWS Amplify Development
Create a Cognito User Pool with Sign-In Aliases using the Amplify CLI
Add Cognito alias support by modifying the CloudFormation template generated for an “auth” resource.
Introduction
I have been working with Amplify and Cognito for several months now and recently encountered a scenario where the Amplify CLI did not meet my needs. I wanted to create an application that requires a user name for sign-up, but allows users to sign-in using an email address after sign-up confirmation. While Cognito supports this feature, the Amplify CLI currently does not.
The Argument for Aliases
A unique identifier is required for every user in a Cognito user pool. There are three types of identifier supported by Cognito; an arbitrary user name, an email address or a phone number. Applications that require public identifiers for users typically use unique user names or a mutable nickname for this purpose — email addresses and phone numbers are generally considered private information that should not be revealed to a wider audience.
I often forget the user names I provided when creating new accounts. Why? Because applications with a large user base often force new users to try several names in response to name collisions. For this reason, email addresses and phone numbers are better suited for account sign-in as they are unique across applications, seldom change and are easy to remember.
A Solution
A Cognito user pool can be configured when created to accept aliases for user names. This feature cannot be enabled on a pool that already exists. Cognito supports any combination of the following aliases; a verified email address, verified phone number or a mutable “preferred” name.
While the Amplify CLI does not currently support the use of aliases, the CloudFormation template it generates can be modified to add this missing feature prior to user pool creation.
I will demonstrate this solution using the following steps:
- Create an Angular application with an Amplify backend environment.
- Use Amplify CLI to generate a CloudFormation template for a Cognito Amplify “auth” resource.
- Edit the resource stack parameters and template to add alias attributes.
- Use the Amplify CLI to create the actual Cognito resources.
- Modify the Angular front-end to add sign-up/sign-in functionality.
- Launch the front-end and use a browser to test alias functionality.
Prerequisites
This demonstration requires some familiarity with AWS, CloudFormation and AWS Amplify tool chain. You can skip to the next step if you are familiar with Amplify development and your environment is already equipped with the necessary tools.
Amplify makes extensive use of CloudFormation for resource management and requires a local AWS profile to do so. Information regarding the AWS CLI, installation, configuration and profiles may be found in the user guide:
This task also requires installation ofnpm
(from Node.js), the Angular CLI and Amplify CLI on the development host.
Installing Node.js is a platform-specific task; installers may be found at:
https://nodejs.org/en/download
The angular-cli and amplify-cli tools are installed using npm:
> npm install -g @angular/cli
> npm install -g @aws-amplify/cli
The following versions were used for the tasks described below:
- npm: 6.14.11
- angular: 11.2.1
- amplify: 4.43.0
Create an Application
Once all prerequisites have been satisfied, navigate to the directory where a the Angular application and amplify backend will be created. Execute the following. The default values for all prompts may be used:
> ng new ngamp
> cd ngamp
> amplify init
The name “ngamp” is arbitrary — any name may be used for this application.
Add Cognito Authentication to the Backend
The next step is to use amplify add auth
to generate the CloudFormation template that will build the Cognito user and identity pools for the application. Choose “manual configuration” and configure as desired, but be sure to select "Username” in response to the prompt "How do you want users to be able to sign in?” and “email” for “What attributes are required for signing up?”
When the command completes, you should find the following directory structure under the root application directory (assuming the “auth” resource was assigned the name “ngampAuth”):
amplify
├── #current-cloud-backend
│ ├── amplify-meta.json
│ ├── backend-config.json
│ └── tags.json
├── README.md
├── backend
│ ├── amplify-meta.json
│ ├── auth
│ │ └── ngampAuth
│ │ ├── ngampAuth-cloudformation-template.yml
│ │ └── parameters.json
│ ├── awscloudformation
│ │ └── nested-cloudformation-stack.yml
│ ├── backend-config.json
│ └── tags.json
├── cli.json
└── team-provider-info.json
Modify the Stack Parameters and Template
The following files in the amplify/backend/auth
directory must be modified to to add alias support:
parameters.json
ngampAuth-cloudformation-template.yml
Add a new aliasAttributes
parameter to the parameters.json
file. This parameter will list the aliases to accept as a user name at sign-in. The list may include any combination of “email”, “phone_number” or “preferred_username”.
“aliasAttributes”: [“email”],
A user pool can be configured to accept both an email address and phone number, but the sign-up process is more involved. Only one alias, phone number or email address, can be confirmed during account creation — the other must be handled programmatically — typically using a Cognito Lambda trigger. More information may be found here:
Make the following changes to the ngampAuth-cloudformation-template.yml:
- Add a new
aliasAttributes
parameter definition under theParameters
section at the top of the template:
Parameters:
.
.
. aliasAttributes:
Type: CommaDelimitedList
- Add an
AliasAttributes
property that references the new parameter in theAWS::Cognito::UserPool
resource definition:
AWSTemplateFormatVersion: 2010-09-09UserPool:
Type: AWS::Cognito::UserPool
UpdateReplacePolicy: Retain
Properties:
.
.
.
AliasAttributes: !Ref aliasAttributes
.
.
.
Create the Cognito User Pool
Once the aforementioned changes have been made, execute an amplify push
to create the “auth” CloudFormation stack and Cognito user pool.
After the push operation completes, open the AWS Cognito User Pools console web page, select the auth resource, and navigate to the Attributes settings. The “Also allow sign in with verified email address” should be checked as shown below:
Create an Application to Test Sign-up and Sign-in
The Cognito console can be used to manually create and confirm new users, but how does it work in an application?
Amplify provides Angular components that can be used to add Cognito-based user sign-up and sign-in dialogs in an app. To do so, you must install additional modules in the root directory of the Angular application:
> npm install aws-amplify @aws-amplify/ui-angular
The following files must be modified to add the Amplify sign-up/sign-in functionality to the app:
src/polyfills.ts
src/main.ts
src/app/app.module.ts
src/app/app.component.html
Add the following statement to the end of the src/polyfills.ts
file:
(window as any).global = window;
Add Amplify and Auth module initialization code to src/main.ts
:
Modify src/app/app.module.ts
to add the Amplify UI module:
Replace the boilerplate content of src/app/app.component.html
with the following:
Start a local front-end server instance using:
> npm start
Use a browser to open (tested using Chrome):
http://localhost:4200
If everything is working correctly, the browser should display the following:
At this point, there should be no users in the Cognito user pool. To create a new user, select the “Create account” link which will bring up the sign-up dialog:
Fill in the form as indicated. Note that an email address cannot be used in the “Username” field; the form will raise an error if one is entered. Click “CREATE ACCOUNT”. If everything is configured correctly, the following form will appear and an email with a confirmation code will be sent to the email address specified in the prior step.
Enter the confirmation code and click “CONFIRM”. The following should appear in the browser:
Click “SIGN OUT” to return to the sign-in dialog. Try signing in with the user name or the email address specified when creating the new account. Either value should be accepted as valid input for the user name and a sign-in with the correct password should succeed. The AWS Cognito console can be used to verify creation of the new user.
-g.b.
References
Amplify authentication guide:
https://docs.amplify.aws/lib/auth/getting-started/q/platform/js
Integrating Amplify with Angular:
https://docs.amplify.aws/start/q/integration/angular
Cognito developer guide:
https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html
CloudFormation user guide for Cognito resources:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_Cognito.html