AWS Cognito Authentication With NodeJS
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
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;
};
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