AWS Amplify and Angular - How to ?
How to configure, initialize and use AWS Amplify, the new CLI based tool chain and Javascript SDK from AWS to manage and use AWS Services.
In this post, we will create a basic Angular Application and enable it to authenticate with AWS Cognito by using AWS Amplify to create the AWS resources and configure it in the Amplify frontend SDK.
Currently AWS Amplify works with the following category of AWS services:
Note: The AWS Amplify has been modularized so, you can just import the module that you need (but for angular > 6 there were issues, so I had to use the packages without the “@” in front of it, I have described that later in this post) )the name of module and npm packages are listed along side the different categories below.
- Core — npm package (@aws-amplify/core): You need this core package for configuring the Amplify to use any of the below.
- Analytics — npm package (@aws-amplify/analytics)
- API — npm package (@aws-amplify/api)
- Authentication(AWS Cognito) -— npm package (@aws-amplify/auth): This post is all about using this in your Angular Application
- Interactions
- PubSub — npm package(@aws-amplify/pubsub)
- Push Notifications
- Storage — npm package(@aws-amplify/storage)
- XR
In this post we will go though the process of creating and using aws amplify to enable AWS Cognito based authentication in an Angular Application.
Pre-Requisite — Setting up Amplify Configuration and Starting a new Angular Application:
Some preliminary steps before you begin this How to:
- Ensure that you have an AWS Account and are familiar with basics of AWS and Angular and their eco systems and terminologies.
- Ensure that you have AWS CLI configured on your system with AWS Profile setup for the AWS account that you will be using for this How to.
Install AWS amplify cli and Create a new Angular Application:
- Install @aws-amplify/cli
$ npm install -g @aws-amplify/cli
2. Check that AWS amplify cli is installed
$ amplify
3. Install and ensure that you have the latest Angular CLI installed
$ npm install --save @angular/cli
$ ng version
4. Create a new angular application ( I am naming my angular application “angular-amplify”, to follow through just choose the same)
$ ng new angular-amplify
5. Go to your newly created angular application directory and install the package and run it to make sure the starter application works
$ cd angular-amplify
$ npm install
$ npm start
6. Install additional npm packages for your angular/frontend application related to AWS Amplify
- aws-amplify — The below npm package needs it, else you will get an error
- aws-amplify-angular — Amplify Angular Components
- @aws-amplify/ui — UI — not listed in the Amplify documentation and one needs to install it for the UI to add AWS themed css style. Just installing this package will not work. One has to also import the following theme and css file in angular project’s styles.scss file, detailed later on in this post.
- @import “~@aws-amplify/ui/src/Theme.css”;
- @import “~@aws-amplify/ui/src/Angular.css”;
$ npm install --save aws-amplify
$ npm install --save aws-amplify-angular
$ npm install --save @aws-amplify/ui
Initialize Amplify related configuration files/folders:
Within the root directory of this project, i.e /angulr-amplify, run the following command
$ amplify init
and then choose the following options, one by one when prompted:
Below lists my choice.
| => amplify init
Note: It is recommended to run this command from the root of your app directory
? Choose your default editor: Visual Studio Code
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using angular
? Source Directory Path: src
? Distribution Directory Path: dist
? Build Command: npm build
? Start Command: npm start
Using default provider awscloudformationFor more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html? Do you want to use an AWS profile? Yes
? Please choose the profile you want to use default
⠴ Initializing project in the cloud...
This should create the following set of amplify configuration file and directories:
<aws-ang-amplify>
|_amplify/
|_ #current-cloud-backend/
|_ amplify-meta.json
|_ .config
|_ aws-info.json
|_ project-config.json
|_ backend/
|_amplify-meta.json
|_.amplifyrc
The details of the above files/directory, along with what they are used for is sufficiently provided within this link AWS amplify Javascript usage.
To understand the terminology, you should have a basic understanding of AWS and associated terminologies and service offerings.
The Angular Application we are creating will just use the AWS Auth or AWS Cognito Service for now, so, let’s create the cloud formation stack template for AWS Cognito.
$ amplify add auth
This should create a directory “auth/cognitoxxxxxxxx” within amplify/backend directory of your project root. This directory should have a newly generated, cognito cloud formation script and a parameter JSON file.
Now, let’s create the actual AWS resources, using the local cloud formation scripts generated by the amplify cli. To create the resources use the following command.
$ amplify push| Category | Resource name | Operation | Provider plugin |
| -------- | --------------- | --------- | ----------------- |
| Auth | cognitoa67f309a | Create | awscloudformation |
? Are you sure you want to continue? (Y/n)
Enter “Y” above. After a few minute, it will create the AWS resource and generate a configuration file “aws_exports.js” within the <angular-amplify>/src folder.
We will use this generated configuration file with information about our newly created AWS resources, to configure AWS Amplify frontend SDK next in our Angular Application.
Moving onto Angular Application now:
Now make a copy of the “aws-exports.js” under “src” directory created from above.
$ cp src/aws-exports.js src/aws-exports.ts
Create a component named “auth” using the following angular CLI
$ ng g c auth
CREATE src/app/auth/auth.component.scss (0 bytes)
CREATE src/app/auth/auth.component.html (23 bytes)
CREATE src/app/auth/auth.component.spec.ts (614 bytes)
CREATE src/app/auth/auth.component.ts (262 bytes)
UPDATE src/app/app.module.ts (467 bytes)
Similarly Create a “home” and “secure” components
Use below command for “home” component creation.
$ ng g c home
CREATE src/app/home/home.component.scss (0 bytes)
CREATE src/app/home/home.component.html (23 bytes)
CREATE src/app/home/home.component.spec.ts (614 bytes)
CREATE src/app/home/home.component.ts (262 bytes)
UPDATE src/app/app.module.ts (541 bytes)
Use below command for “secure” component creation.
$ ng g c secure
CREATE src/app/secure/secure.component.scss (0 bytes)
CREATE src/app/secure/secure.component.html (25 bytes)
CREATE src/app/secure/secure.component.spec.ts (628 bytes)
CREATE src/app/secure/secure.component.ts (270 bytes)
UPDATE src/app/app.module.ts (623 bytes)
At this point we have our AWS Amplify configuration files created, we have a basic angular application setup with the components: “auth”, “home” and “secure”
Our App URL setup for our simple angular demo application. Nothing fancy here.
/ — will load “home” component/page (default/root page)
/auth — will load the auth component/page
/secure — if logged in, will load the secure component/page, or will redirect to /auth and after successful sign up, take one to this component/page
Check that the angular application works:
$ npm start
Configuring Angular Application to use AWS Amplify SDK:
Ensure that your “aws-exports.ts” file is something like below based on your aws-exports.js file:
export const awsmobile = {
'aws_project_region': 'us-east-1',
'aws_cognito_identity_pool_id': 'us-east-1:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX',
'aws_cognito_region': 'us-east-1',
'aws_user_pools_id': 'us-east-1_XXXXXXXXX','aws_user_pools_web_client_id': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXX'
};
Change main.ts to add the following code to configure Amplify for your application:
import Amplify from 'aws-amplify';
import * as awsamplify from './aws-exports';
Amplify.configure(awsamplify.awsmobile);
Now run your application again:
$ npm start
You may get some buffer and stream issues like below:
ERROR in node_modules/aws-sdk/clients/acm.d.ts(133,37): error TS2580: Cannot find name ‘Buffer’. Do you need to install type definitions for node? Try `npm i @types/node`.
....
If you do get the above error please look at the following link:
To solve the above issue as per the above document:
“To resolve these issues, either add "types": ["node"]
to the project's tsconfig.app.json
file, or remove the "types"
field entirely.”
so change the tsconfig.app.json from below:
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"types": []
},
"exclude": [
"test.ts",
"**/*.spec.ts"
]
}
to:
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
// "types": ["node"]
},
"exclude": [
"test.ts",
"**/*.spec.ts"
]
}
Now execute below command to restart the Angular application and go to “http://localhost:4200/”, to ensure that your starter angular application works fine.
$ npm start
If your application main page comes out blank or if you see the following error when you right click and check the console:
Uncaught ReferenceError: global is not defined
at Object../node_modules/buffer/index.js (index.js:43)
at __webpack_require__ (bootstrap:78)
at Object../node_modules/aws-sdk/lib/browserHashUtils.js (browserHashUtils.js:1)
at __webpack_require__ (bootstrap:78)
at Object../node_modules/aws-sdk/lib/browserHmac.js (browserHmac.js:1)
at __webpack_require__ (bootstrap:78)
at Object../node_modules/aws-sdk/lib/browserCryptoLib.js (browserCryptoLib.js:1)
at __webpack_require__ (bootstrap:78)
at Object../node_modules/aws-sdk/lib/browser_loader.js (browser_loader.js:4)
at __webpack_require__ (bootstrap:78)
To fix the above issue, add following code to your index.html before the </head> tag
<script>
if (global === undefined) {
var global = window;
}
</script>
check the following link for details (scroll to the bottom):
Once again check to ensure that your angular application works:
$ npm start
Remove all the default from the starter application in index.html and also create the following routes in your application route:
const routes: Routes = [
{ path: '', component: HomeComponent, pathMatch: 'full' },
{ path: 'auth', component: AuthComponent, pathMatch: 'full' },
{ path: 'secure', component: SecureComponent, pathMatch: 'full' },
];
Change your index.html to look like below (keep things simple, we are not trying to achieve UI uniqueness here):
<div style="text-align:center">
<h1>Welcome to {{ title }}!</h1>
</div>
<h2>Links to the Pages </h2>
<ul>
<li><h2><a routerLink="/">Home</a></h2></li>
<li><h2><a routerLink="/auth">Auth</a></h2></li>
<li><h2><a routerLink="/secure">Secure</a></h2></li>
</ul>
<hr>
<router-outlet></router-outlet>
<hr>
Again make sure you application runs:
$ npm start
If everything went well your application should look like below:
Now import the AmplifyAngularModule and AmplifyService into your main “app module.ts”, which should look like below:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AmplifyAngularModule, AmplifyService } from 'aws-amplify-angular';import { AppRoutingModule } from './app-routing.module';import { AppComponent } from './app.component';
import { AuthComponent } from './auth/auth.component';
import { HomeComponent } from './home/home.component';
import { SecureComponent } from './secure/secure.component';@NgModule({
declarations: [ AppComponent, AuthComponent, HomeComponent, SecureComponent],
imports: [ BrowserModule, AppRoutingModule, AmplifyAngularModule],
providers: [AmplifyService],
bootstrap: [AppComponent]
})export class AppModule { }
Go to “auth.component.html” and replace the content with below:
<amplify-authenticator></amplify-authenticator>
Save and re-start the application:
$ npm start
Go to the Auth Link and you should have the auth component displayed:
Now create an account and follow the auth process. You have now successfully enabled your angular application to have authentication using AWS cogito and AWS Amplify SDK
… Some more fancy stuff coming soon