How to Add JWT Authentication to NestJS Apps
Tags: webdev, javascript, typescript, beginners
Published: 2023-01-28 05:25:06

###Introduction

Authentication is an important part of our applications. From time to time, there are many ways to handle authentication. With each requirement, we find the suitable approach to handle authentication.

- This article is a simple tutorial on how to implement authentication with NestJS, before go into the guide, I’m going to demonstrate the technologies that are going to be used in the guide

- JWT or JSON Web Token is an industry standard **RFC 7519** method for representing claims securely between two parties.
Passport is the most popular Node authentication library, well-known by the community and successfully used in many production application, **NestJS** has supported it outside the box with `@nestjs/passport`

###Installation 
First, we create the project

```
nest new your-project-name
```

Then we add the dependencies

```
yarn add @nestjs/passport passport passport-local passport-jwt @nestjs/jwt 
```

We are going to use `mongoose` to store the data

```
yarn add mongoose @nestjs/mongoose
```

###Generate modules, services and controllers
For the authentication, we need 2 modules `AuthModule` and `UserModule` , each of them need controller and service files

####Auth module:

```
nest g module auth
nest g service auth
nest g controller auth
```

####User module

```
nest g module users
nest g service users
nest g controller users
```

###Define schema and interface
We need an `UserSchema` and an `User` interface, let’s create the `user.model.ts` file


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dpfv672byl78k5340tvm.png)

###Create User Service


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q6rns3effrmxu40kdbkf.png)

We created the `users.service.ts` before, next we create 3 methods for the sign up ( createUser ), get all users ( getUsers ) and get an user ( getUser )

###Create User Module an Controller


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vt4cfcwyi04ok21qx0rw.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ndiyhrghzxixueubqa92.png)


Nothing much to say about these files, I created 2 routes in the `UsersController` to sign up and get all users and import all we have with users to the `users.module.ts` file

Only thing to keep in mind is the `@UseGuards(AuthGuard('jwt))` part, which means we can’t access this route without logged in and have the jwt

###Auth Service


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0b4qbv53xfu9xsiear3z.png)


There are 2 methods in the `AuthService` , one is to validate if the user exist in our database with correct credentials, the other one is to return an `access_token` which is a JWT assigned with an `username`

###Strategies
We have to create the `strategies`, in this guide I will create 2 strategies, one is `LocalStrategy` and the other is `JwtStrategy`

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xa3kva9sdcxkw40jmwpl.png)

The `LocalStrategy` serves a purpose when we need to validate the `username` and `password` before going deeper into the controller. In this case, I create the built-in `validation` method with the `validateUserCredentials` from the `AuthService`


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ob9yu1hoz75cqklpyoki.png)

For the `JwtStrategy` we extend the `PassportStrategy` from the `@nestjs/passport` library just like above, then we return an object consists the `username` . The constructor need to extract the JWT from Header Bearer token (the `access_token`). We also need a secret key for JWT Strategy, mine is `SECRET_KEY` but I suggest you to use a more secure way to store keys.

###Auth module and controller


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j6e2thxu4k2q5081iagv.png)

Like the `UserController` above, we define the route for authentication, in this controller is the `login` route. You can see I used `AuthGuard('local')` from the `LocalStrategy` above. So we only proceed to login after the validation succeeded.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w6ns1mqofrehm6z9z1u9.png)


Nothing much to say about the `auth.module.ts` file, we import all the modules we need assign the `providers` , `controllers`

###App module
Every NestJS project comes with the `app.module.ts` file that centralizes all the modules


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rbdda22j0zczs5u6wff0.png)


**Note: I used MongoDB Atlas to create a cloud database, but you can decide what database to use**

###Conclusion
Let’s try our APIs in Postman to see if it works

First, start the server with:

```
yarn start:dev
```

Then open Postman, we’re gonna start with the `login` route


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ftekk37a4ew6hqcbh7lo.png)

We can see the server returns `access_token` for us, we will copy this into every guarded API, like the `getUsers` from `UserController`


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ad40gog1rmxcuvf9ytf.png)

That’s all, isn’t that hard right, you can check out [my source code here.](https://github.com/leduc1901/nestjs-jwt-auth)

###Last Words
Although my content is free for everyone, but if you find this article helpful, [you can buy me a coffee here](https://www.buymeacoffee.com/kylele19)