AWS Cognito Authentication With NodeJS

Mohammad Faisal - Jan 21 - - Dev Community

To read more articles like this, visit my blog

When using AWS Cognito user pools, we usually use a client-side library like aws amplify to manage all the authentication processes.

But there can be some situations where you must handle the authentication process yourself.

When users use a UI to log in using their email and password and get a JWT token using that token, we call our API calls.

The Problem

There are some scenarios when we can’t use the UI to authenticate. For example,

  • We want to make a call from one lambda to another lambda that is protected by authorizer.

  • We want to call a protected lambda from our monolith backend application.

So somehow, we need the authentication token to make these calls.

How do we do that?

Prerequisites

I am assuming you already have a working NodeJS application. Or you can do this using a simple Lambda function as well. If you want to test the function, download the following repo.

https://github.com/Mohammad-Faisal/nodejs-typescript-skeleton

And we are all set up!

Step 1: Install the dependency

First, install the following dependency.

npm i amazon-cognito-identity-js
Enter fullscreen mode Exit fullscreen mode

This is the only dependency you need.

Step 2: Design the function

Here is the getToken function that is used to get the token using email and password.

    import { CognitoUserPool, CognitoUser, AuthenticationDetails } from 'amazon-cognito-identity-js';

    const Username = 'USER';
    const Password = 'PASSWORD';
    const UserPoolId = 'USER_POOL_ID';
    const ClientId = 'CLIENT_ID'; // Your App client id (add via Console->Cognito User Pool)

    const getToken = async () => {
        const userPool = getUserPool();
        const cognitoUser = getCognitoUser(userPool);
        const authenticationDetails = getAuthenticationDetails();

        return new Promise((resolve) => {
            cognitoUser.authenticateUser(authenticationDetails, {
                onSuccess: function (result: any) {
                    const token = result.getIdToken().getJwtToken();
                    resolve(token);
                },
                onFailure: function (err: any) {
                    console.log('error is ', JSON.stringify(err));
                    resolve(null);
                }
            });
        });
    };

    const getUserPool = () => {
        const poolData = {
            UserPoolId: UserPoolId,
            ClientId: ClientId // Your App client id here
        };
        const userPool = new CognitoUserPool(poolData);
        return userPool;
    };

    const getCognitoUser = (userPool: CognitoUserPool) => {
        const userParams = {
            Pool: userPool,
            Username: Username
        };
        const cognitoUser = new CognitoUser(userParams);
        return cognitoUser;
    };

    const getAuthenticationDetails = () => {
        const authenticationData = {
            Username: Username,
            Password: Password
        };
        const authenticationDetails = new AuthenticationDetails(authenticationData);
        return authenticationDetails;
    };
Enter fullscreen mode Exit fullscreen mode

To get this function working, you will need several pieces of information.

User Name : The actual credential of a valid user in the user pool.

Password : The password of the user

UserPoolId : Id of the user pool.

ClientId : You can get it via AWS console.

Output

After getting these pieces of information, you can call the getToken function, and if everything goes well, you will get the token back.

Now, you can make API calls to other secured lambdas without authenticating via the UI.

That’s it for today. I hope you learned something new!

You can reach me via LinkedIn or Personal Website

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .