Securely store client files in S3 using AWS cognito (Cognito + S3 + Ionic sample application)

Introduction

In this example series, we will build an ionic4 (angular6) client app where user can signup and manage his/her images in a personal space. No one other than the user signed will have access to the files uploaded. We use aws cognito for authentication and authorization and S3 to store the files.

Demo

Components

AWS Cognito — User management (signup, verify user, Authentication, Authorization)

Architecture

Prerequisites

$node -v
v8.9.4
$npm -v
5.6.0
$ionic -v
_ _
(_) ___ _ __ (_) ___
| |/ _ | '_ | |/ __|
| | (_) | | | | | (__
|_|___/|_| |_|_|___| CLI 4.0.1

Steps Required

Step 1: Create S3 bucket

<?xml version=”1.0" encoding=”UTF-8"?> <CORSConfiguration xmlns=”http://s3.amazonaws.com/doc/2006-03-01/"> 
<CORSRule> <AllowedOrigin>*</AllowedOrigin> <AllowedMethod>PUT</AllowedMethod> <AllowedMethod>GET</AllowedMethod> <AllowedMethod>POST</AllowedMethod> <AllowedMethod>DELETE</AllowedMethod> <MaxAgeSeconds>3000</MaxAgeSeconds> <ExposeHeader>ETag</ExposeHeader> <AllowedHeader>*</AllowedHeader> </CORSRule> </CORSConfiguration>
{ 
"Version": "2012-10-17",
"Statement": [
........
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [ "s3:PutObject", "s3:GetObject", "s3:DeleteObject" ],
"Resource": [
"arn:aws:s3:::<bucket-name>/<user-defined-prefix>/${cognito-identity.amazonaws.com:sub}",
"arn:aws:s3:::<bucket-name>/<user-defined-prefix>/${cognito-identity.amazonaws.com:sub}/*"
]
}
]
}
  • Password policies
  • Message customization (email / sms) for user verification.
## Create new project 
ionic start ionic4Cognito sidemenu --type=angular
ionic serve
## Install angular amplify npm install --save aws-amplify
npm install --save aws-amplify-angular
## create a deployment package
npm run build --prod
## create a new production deployment package 
npm run build --prod
## Romove all existing files
aws s3 rm s3://<your-bucket-name>/ --recursive
## Copy new files to S3
aws s3 cp www/ s3://<your-bucket-name> --recursive --acl public-read

Authentication and Authorization

On sign-in, cognito issues three tokens to the client.

IdToken

IdToken contains information about the identity of the user like name, email etc.

AccessToken

Users can use this token to get authorised access to aws resources.

Request URL: https://<bucket-name>.s3.ap-southeast-2.amazonaws.com/private/<user specific path>/images/icons8-calendar-50.png
Request Method: PUT
Status Code: 200 OK
......
Authorization: AWS4-HMAC-SHA256 <more here>
Content-Type: image/png
.......

....Image data .......

RefreshToken

RefreshToken can be used to retrieve new IdToken and AccessToken.

Conclusion

It was pretty quick to build an ionic app with secure user access using aws cognito. Lot of heavy lifting was done by aws like user storage, notifications, token issuing, user management etc. When you want to quickly put together an app with user authentication / authorization, it is worthwhile considering aws cognito as an option.

Melbourne, Victoria