Over the last couple of days, I decided to take a bit of a dive into AWS’s Amplify service and see what exactly it had to offer in terms of creating and deploying a web-based application. As Amazon describes it, “AWS Amplify is a set of purpose-built tools and features that lets frontend web and mobile developers quickly and easily build full-stack applications”, so I was curious to see really how quick and easy this process was. For this article, we are going to be looking at implementing authentication using the tools the Amplify CLI provides, and try to gain understanding of what is going as we make use of it.
The project I decided to use this for used an Angular front-end. As for the backend services, the goal was to use as many of the services as possible provided in the Amplify ecosystem. Setting up amplify was simple enough. First, I needed to install the Amplify CLI via npm with npm install -g @aws-amplify/cli@7.6.5
then run amplify configure
, which provided a simple step-by-step guide to getting hooked up with my AWS account and creating an IAM user for Amplify to provision resources with.
Once the initial set-up for the Amplify CLI was complete, running amplify init
ran me through configuring the Amplify project for my desired front-end framework. The amplify init
command provisions a few resources for you once the configuration is complete. It creates a CloudFormation stack for your project. Within the stack it also creates template roles (auth and unauth) to allow authenticated and unauthenticated users different access. Lastly, a deployment bucket in S3 is created. This deployment bucket contains some meta-data for your project as well the current backend configuration
Probably one of the most common features seen in web-apps today is authentication of some form or another. Be it for e-commerce, social media, or other web app categories, chances are it’s there. To begin setting up the auth, the command amplify add auth
brings up another step-by-step output in the terminal to configure the authentication processs, including configuration for 3rd party providers like Facebook and Google. There is a default configuration that can be used for quick set-up, but for the purposes of this article, I decided to go down the manual configuration rabbit hole. I used default settings for user pool name, and selected authentication via email. I also requested that a user be asked to provide their full name. By default, new users receive an email with a verification code when creating a new user and AWS allows you to customize both the subject of that email and the body. You can also set parameters for passwords to have a certain level of complexity (length, special characters, upper and lowercase etc). Once all of the settings have been applied, the authentication resource is added locally. The amplify push
command will take this resource and publish it in the cloud. Publishing will trigger a CREATE event in CloudFormation. This event includes the creation of a new User Pool for the application.
Implementing the authentication in the frontend can be done either manually, or through the use of template components. AWS provides a ready to use Authenticator component which can be popped into your application with a simple import. I decided to take a look at what they had for Angular, making use of their Amplify-UI guide which can be found here. While it’s quite easy to follow, I found that there were a couple things missing from the guide that would have saved me some headache along the way. After importing the fonts and configuring a polyfill, we move on to the Components section of the UI guide and select the Authenticator Component found here. The docs do a good job highlighting the module import you need to add to your app.module.ts
file but it’s what is unhighlighted and not included that are key to getting this component to work. Asides from the import of the AmplifyAuthenticatorModule
, an import of aws-config from ../aws-exports
and an import of Amplify from 'aws-amplify'
are also required. Importing aws-config
gives you access to the environment variables unique to your Amplify environment while the Amplify
import contains the methods needed to establish that connection to the Amplify services. You will also need to add below the import statements Amplify.configure(awsconfig);
. This part in particular was completely ommitted from the documentation. Failing to perform these steps before serving up your application will lead to an error about Amplify not being configured properly. Another important step to note, in your tsconfig.json, under the compilerOptions
property, it is also necessary for us to add // @ts-ignore
to the top of our app.module.ts
file, to ignore errors relating to the fact that aws-exports
is a JS file. If we do not add this, our IDE throws an error due to aws-exports
having an implicit ‘any’ type. A complete example of all the imports and statements needed to get the component functioning properly can be found in the snippet of app.module.ts
below:
App.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
//Amplify Imports
//@ts-ignore
import awsconfig from '../aws-exports';
import Amplify from 'aws-amplify';
import { AmplifyAuthenticatorModule } from '@aws-amplify/ui-angular';
//Apply Amplify Configuratons
Amplify.configure(awsconfig);
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
AmplifyAuthenticatorModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Last but not least, we need to place our Authenticator component inside of our web-app’s entry point, for Angular, that is going to be our app.component.html
file. We can get rid of everything inside of that file from when we initialized the project and replace it with the following:
app.component.html
<amplify-authenticator>
<ng-template
amplifySlot="authenticated"
let-user="user"
let-signOut="signOut"
>
<h1>Welcome {{ user.username }}!</h1>
<button (click)="signOut()">Sign Out</button>
</ng-template>
</amplify-authenticator>
The end result of all this should leave us with a fairly decent looking authentication screen, with options for login and sign-up when we finally ng serve
the application. When we create our first user, we can navigate to the AWS console, go to Cognito, select our user pool, and find the user that we just created with statistics showing us if the user has been enabled, confirmed (via email), and when the user was created and last update.
Final Thoughts
Getting the auth portion of this application set up was definitely easier than I expected. Considering the number of tasks that were handled (eg. email verification) in conjunction with the pre-built component it definitely took less time and provided me with more flexibility than I had initially anticipated. There were definitely some roadblocks along the way, especially with the frontend implentation and the docs neglecting a few important details. But overall, I never ran into an issue that simple, well-worded google search couldn’t get me by.