Serverless Authentication with AWS Cognito and JavaScript

In a traditional web application, authentication is handled by server-side code and users are managed in the database layer. In the world of serverless apps, we can offload the heavy-lifting to a managed authentication service like AWS Cognito to simplify it.

This post focuses on JavaScript code to authenticate users and manage sessions through AWS Cognito.

The entire solution can be found in this repo.

The most important concept with AWS Cognito is to understand the difference between User Pools and Identity Pools. In a nutshell, User Pools manage user authentication and Identity Pools manage user authorization through IAM roles and permissions. For authentication, user pool is all you need. However, without setting up IAM role through Identity Pool, the authenticated user cannot take action on AWS resources, such as uploading files to S3 or interacting with DynamoDB. This NewStack blog post is excellent in explaining the difference.

Setting up users in Cognito

Users can be set up in Cognito through user interface (see AWS official documentation). Usually, we need to write both sign in and sign up logics to manage users. When the user base is limited, sign up logic might not be needed. Without sign up logic, we need to run AWS command to confirm the user by manually changing their password.

Once the user is created in Cognito, we can run the command below to reset the password so that the user status becomes confirmed.

aws cognito-idp admin-initiate-auth --user-pool-id pool_id ^
--client-id client_id --auth-flow ADMIN_NO_SRP_AUTH ^
--auth-parameters USERNAME=your_user_name,PASSWORD=initial_password

aws cognito-idp admin-respond-to-auth-challenge ^
--user-pool-id pool_id --client-id client_id ^
--challenge-name NEW_PASSWORD_REQUIRED ^
--challenge-responses NEW_PASSWORD=new_password,USERNAME=your_user_name ^
--session session_string_from_the_previsou_command

Dependencies

Interacting with any AWS service is easy thanks to their excellent SDK. We are using Congito specific JavaScript SDK, amazon-cognito-identity, which is part of aws-amplify. All you need to do is to import them in the script tag at the bottom of the body. Here is the example of sign in html page.

Signing in

The function can be invoked on clicking the sign in button. It makes an API call to Cognito and returns a token. If successful, redirect the user to the protected page. You need to obtain user_pool_id and client_id from Cognito console, which should be straight-forward. The code is base on the example from AWS.

Checking user

We can call getCurrentUser() method to see if the user is logged in or not. If there is not current cognito user in the session, it redirects to the sign in page. Index page is not visible when the user is not logged in and hits the index page url.

Signing out

To sign out, we call signOut() method on the user. It will sign out the user and redirect to sign in page.

Front-End
TypeScript: type aliases to check type equality

This post is to analyse how the type equality check by using type aliases proposed by Matt Pocock in his twitter post. These type aliases allow us to elegantly express type equality checks in unit tests. All we need to do is to pass the output and expected types in …

Front-End
Fixing it.only type error in Jest

If you are getting a type error with it.only in Jest, it could be due to incorrect TypeScript typings or incompatible versions of Jest and TypeScript. To resolve this issue, you can try the following steps: Make sure you have the latest versions of Jest and its TypeScript typings installed …

Front-End
yup conditional validation example

Here’s an example of a Yup validation logic where the first input field is optional but, if filled, it must contain only alphabetic characters, and the second input field is required: import * as Yup from “yup”; const validationSchema = Yup.object().shape({ firstField: Yup.string().matches(/^[A-Za-z]*$/, { message: “First field must contain only …