Authentication with AWS Cognito and NestJS

Jacob Do
Webtips
Published in
4 min readJun 8, 2020

If you have landed here after a couple of incomplete guides on how to implement AWS Cognito into a NestJS application, then I hope you’re in luck as I will try to fill in the gaps you might have.

Let us start from the very beginning.

Set up AWS Cognito account

Head over to https://aws.amazon.com/cognito/ and sign in with your AWS account.

Then type in Cognito in the search box and click on the only search result there:

Finding Cognito

Then:

  • Press “Manage user pools”
  • Press “Create a user pool”
  • Enter the name of your user pool (the name of your project will do)
  • Press “Review defaults” as the other option takes longer and we really want to just get through this bit
  • Finally, press “Create pool”

If all went well, you should be presented with a screen like this:

Cognito default dashboard

From here, find and click “App clients” in the sidebar.

  • Press “Add app client”
  • Enter the name of the app client, say “My project’s API”
  • IMPORTANT: untick “Generate client secret”, otherwise this App client will not be usable in a NestJS application
  • Then scroll to the bottom of the page and press “Create app client”

Again, if you leapt through the hoops with me, you should see the following:

App client information

From here we will use the “App client id” value, but we will come back for it later.

Create auth module

Next up, we need to create an auth module that will take care of all things related to our authentication. To do that, start by running the following command at the root of your NestJS project:

nest g module auth

This command will create a file called auth.module.ts inside of src/auth.

Then we’ll create a file called auth.config.ts inside of src/auth. This file will hold all the values that we need to communicate with AWS Cognito:

We also need to provide node-fetch in the global context of the app, so our main.ts file should look like this:

Adding node-fetch to main.ts

We will be using environment variables here and while setting up using them is not directly related to the task at hand, it is the prudent thing to do, so we’ll quickly look at how to do that.

In order to use .env in our NestJS application, we first need to install nestjs/config:

yarn add @nestjs/config

When that’s done, let’s create a .env file at the root of the application and also enable our app to access values from the file by importing and setting up ConfigModule in app.module.ts as follows:

Importing ConfigModule

Now our .env file is accessible in our app.

Next, let’s add the following content to your .env file:

Declaring Cognito .env variables

COGNITO_USER_POOL_ID can be found in Cognito User Pools -> General Settings:

Cognito user pool id

COGNITO_CLIENT_ID is the “App client id” I mentioned before in the article when we were creating our Cognito user pool.

Finally, COGNITO_REGION is just the first part of your COGNITO_USER_POOL_ID . I’ve broken it out into its own variable just to be able to re-use it conveniently.

For the next bit, we also need to install amazon-cognito-identity-js:

yarn add amazon-cognito-identity-js

Next, in order to be able to use our AuthConfig inside of AuthService , we need to declare the former as a provider inside of auth.module.ts :

Making AuthConfig available in AuthModule

Now that that’s out of the way, let’s create our AuthService by running:

nest g service auth
authenticateUser method in AuthService

Finally, in order to be able to test out our functionality, we need to create a controller that will use the above service. We can create our AuthController by running:

nest g controller auth

Our controller will be simple and only have one method login , that will handle the /auth/login route:

In here, we simply call the authenticateUser method from AuthService and return the result as well as we catch any exceptions that return a BadRequestException along with the actual error message so that we can inform the consumer what exactly went wrong.

Now the only thing that is left is to test it out, I will use Postman https://www.postman.com/downloads/ for this part and you’re welcome to do the same.

If you got the following response for the request visible in the screenshot, it means that you have successfully attempted to verify credentials against your AWS Cognito user pool:

Validation response from AWS Cognito

A working GitHub example for the code produced in the course of this article can be found here: https://github.com/jacobdo2/nestjs-cognito-example

Hope it works for you 🤞 and let me know in the comments if it does not — we’ll figure it out!

--

--

Jacob Do
Webtips
Writer for

HTML engineer by day, Meme connoisseur by night