Upload file(s) to AWS S3 bucket using temporary credentials via AWS Cognito-AWS SDK javascript in Angular application
For the past 8 to 10 months, have been preparing for AWS certification(s) and was successful in getting through AWS Developer Associate, AWS Architect Associate but failed AWS SysOps with 689/1000 score where the passing score was at 720/1000[Will re-attempt shortly]. Although I am not sure how much do these certifications help in terms of career growth, one thing for sure is the time and effort that we put in preparing for the exam does give you an overall picture of what major AWS services are while helping you familiarize with terminology within AWS domain( i.e., Speaking the language of AWS :-) ). At least from the AWS perspective, IMHO getting certified would be the best way to get started. Lastly, would like to thank #awsdocs, #acloudguru,#whizlabs,#quizlet for helping with my journey towards AWS.
The theory is very important, but for us to really understand how things work, one needs to have hands-on experience. In AWS, for any developer who is getting their hands dirty for the first time, I feel uploading files to S3 bucket via AWS SDK would be like writing their first “Hello World”. Here, I will go a little bit further and add AWS Cognito and IAM into the recipe for accessing contents from S3 buckets.
I would recommend reading below article from AWS blogs which gives you a quick overview of what is AWS Cognito and how it is integrated with Identity Access Management (IAM)
In the above article, the author (Ed Lima, Solutions Architect) uses below anology to explain what is AWS Cognito in AWS Cloud:
To use a metaphor, Amazon Cognito User Pools provided you with a passport (JWT-JSON Web Tokens) that you can use at the airport counter to retrieve a boarding pass (access credentials) from an identity pool. With your valid boarding pass, you are then allowed to go to the airport gate and board your flight to the AWS Cloud, which is a fitting analogy for this post. The boarding pass is only valid for a specific time. In application terms, the token (passport) authenticates the user and the issued temporary credentials (boarding pass) authorize the access to connect (board).
1. Creating an AWS Cognito Identity pool
Step 1: Follow below flow and go to Manage Identity Pools dashboard.
AWS Console → Cognito → Manage Identity Pools
Click on create new Identity pool button which will launch below the screen.
Provide identity pool name and ensure to check on the “Enable access to unauthenticated identities” checkbox and click on “Create Pool”.
New Cognito roles will be created for both authenticated and authenticated identities. You can rename or leave the default values.
Keep a note of the identity pool Id, which we will be using later to access content from the S3 bucket. Of course, you can always go back to AWS Cognito dashboard and get it back.
2. Creating new Policy, assign to a Group and create an IAM user with programmatic access
AWS Console → Services → IAM →Policies → Click on “Create Policy”
Instead of providing full S3 access, I chose to have limited access. For this demo purpose, selected all options under List, “GetObject” from Read and “PutObject” from Write operation. However, unless the S3 bucket ARN value is provided, the policy cannot be created due to the warning messages as shown in the above screenshot. From Services console, you can create a new S3 bucket or use an existing one that is already created ( see below on how to create S3 bucket)
Click on the newly created S3-fileupload-demo policy, verify that the bucket name is mentioned in the Resources section. If required, the bucket name can be changed different one later.
Click on Policy Usage, and attach and search for the above Cognito roles that we created in the previous steps
Attach both authenticated and unauthenticated Cognito roles like below
Next, we will need to create a new user and provide only programmatic access and attach to the above group.
Search for the new group that we created in the above steps.
Adding newly created user to the group with Cognito roless
3. Creating S3 bucket with appropriate bucket policy and CORS settings
AWS console →S3 →Create New Bucket.
Provide a bucket name, this should be unique globally.
Leave the settings as they are for above and below screens.
Finally, click on Create Bucket.
Next, we will need to update the bucket policy, here we will use the policy generator tool.
In place of principle, copy paste the ARN name of the user that we created in step 2 ( IAM user). For the Amazon Resource Name (ARN) field, enter the S3 bucket’s ARN value.
This is how the policy would look like.
Copy paste the policy json into the bucket policy section and save.
Update the CORS section appropriate options.
<?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>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<ExposeHeader>ETag</ExposeHeader>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Now, we are at a position that all the required settings required from AWS perspective are done and now we will use the AWS SDK to upload a file and list all file names inside a bucket.
4) Uploading a file into S3 via AWS SDK and get the list of file names within an S3 bucket
To install AWS SDK via npm
npm install aws-sdk
Here is the GitHub project which has working GitHub pages link where anyone could enter their own identity pool and bucket name and upload files to their own S3 bucket and get the list of all files within the bucket
Script Debug-Network tab activity indicates that uploading a file to S3 using Identity Pools involves an ajax call to AWS Cognito service with identity pool id as the input parameter first which returns the short time to live security token which can be used to access AWS services like S3, DynamoDB etc.,
I hope you like the post, let me know if there any issues or corrections needed for the post