Angular and the REST, Nest.js and JWT
Tags: angular
Published: 2019-08-01 20:36:37

In this, the final installment on Angular and the REST, I implement authentication on the backend Nest.js Web API using Passport.js and JWT (JSON Web Token). In addition, I add a new authentication module on the Angular app side, so access is restricted to authenticated users only by way of Login.

The first installment of this week, I introduced Nrwl Nx Workspace and created the Movie Tracker monorepo workspace including a Nest.js app for the backend and an Angular app for the client-side. The app so far has a full implementation of the CRUD actions and movie search. On the client-side, we built an Angular v8 app that communicates with the backend RESTful Web API by means of a Movie Tracker Service. The app displays all movies, allows the user to filter the movies, add a new movie, edit an existing movie and delete a movie.

Here’s a link to that article.
[Angular and the REST with Nest.js](https://dev.to/thisdotmedia/angular-and-the-rest-with-nest-js-2glo).

Today, let’s start by adding support for Passport and JWT authentication to our Nest.js app.

> In case you have not read the entire series on Angular and the REST, these are the links: 

- [Angular and the REST] (https://dev.to/thisdotmedia/angular-and-the-rest-4ho7)
- [Angular and the REST with JWT Authentication] (https://dev.to/thisdotmedia/angular-and-the-rest-authentication-with-jwt-5em0).

[Passport.js] (http://www.passportjs.org/) is one of the most mature authentication middlewares known for Node.js development. It provides a high level of flexibility in terms of choosing what authentication strategy to use to authenticate your users.

Nest.js offers the [@nestjs/passport] (https://github.com/nestjs/passport) authentication library that wraps the functionality of Passport.js and integrates smoothly with Nest.js Dependency Injection system.

Let's start implementing authentication on the backend side of the Movie Tracker app.

You can find the source code of this article at this GitHub [repo](https://github.com/bhaidar/movie-tracker/tree/add-authentication-server).

##Adding Authentication to Nest.js
First of all we start by installing a set of NPM packages that we need to add authentication to the app.

Run the following command to install the packages:
`yarn add @nestjs/passport passport passport-local passport-jwt bcryptjs`

In addition, I will install the corresponding Typescript definitions for the following packages by running this command:
`yarn add @types/passport @types/bcryptjs -D`

The `@nestjs/passport` library counts on the `passport`,`passport-local` and `passport-jwt` packages and therefore it is required to install them too.

Passport.js is usually used and configured as a Node Middleware. However, in Nest.js, the @nestjs/passport library providers the `AuthGuard`. This is used to imply that Passport authentication is required on a specific Controller or Action in the Controller.

> To learn more about guards in Nest.js go to their official documentation on [guards](https://docs.nestjs.com/guards).

Therefore, to ensure a request is authenticated prior to accessing a Controller or Action you decorate your Controller or Action with this guard (or you can [define your guard globally](https://docs.nestjs.com/guards#binding-guards) for all the controllers). The rest is handled by @nestjs/passport and passport together.

**Step 1**
Let's do a change on the `ormconfig.json` file to disable `automatic synchronization` and show you how we can start using migrations to control what is being changed in the database.

Replace the content of the `ormconfig.json` file located in the root folder of the workspace with the following:
{% gist https://gist.github.com/bhaidar/11452693e365233fd54c68207c35d2bc %}

The named connection, the first, is used by the application when it runs. The second is the nameless or default and used by the TypeORM CLI tools to generate or create migrations and run them too.

Once a new migration is generated or created, it is automatically stored inside the path `apps\api\migrations`. Once a migration is run, the Nest.js app is built, the output files are copied to the path `dist\api\migration` and the migration is run from there. This is all configured in `ormconfig.json` file.

At this stage, you should remove the old Docker container by following the steps below:

- Run `docker ps -a`: This command lists all containers created on your machine (both running and not)
- Locate the Docker Container ID for the `Postgres` container and run this command: `docker stop {DOCKER-CONTAINER-ID}`
- Remove the container by running this command: `docker rm {DOCKER-CONTAINER-ID}`

Then, add the following NPM scripts to the `package.json` file to make it easy to interact with TypeORM CLI:
{% gist https://gist.github.com/bhaidar/4f7aa3d7a1d938b0c3ae6790f6d127bf %}

The scripts added are used to generate a migration based on changes introduced to the entities in the app, create new empty migrations (you will fill in the blanks) and run SQL queries against the database using the TypeORM CLI.

**Step 2**
Add the `UsersModule` to manage users in the backend app. Create the following files as shown in the figure below:

![](https://thepracticaldev.s3.amazonaws.com/i/uv8rstxusncal5pfeeqv.png)

The `user.entity.ts` file contains the User Entity:
{% gist https://gist.github.com/bhaidar/a7eb7c7043e85d0f1db62f614673a846 %}

The Entity defines the columns that belong to a single User. Notice the implementation of the `@BeforeInsert()` hook. I use this hook to hash the password using the `bcryptjs` library before storing the User Entity record in the database.

The `users.service.ts` file contains the `UserService`:
{% gist https://gist.github.com/bhaidar/ba29f04e2d49d1582102a644083b3c60 %}

Currently this service provides implementation for a single `findOne()` method that retrieves a user from the database based on the username.

In case you want to implement a full user management service you can add further methods (create user, etc.)

Finally, the `users.module.ts` file defines the user module:
{% gist https://gist.github.com/bhaidar/d5f1a336b3ffa3115e98d7a89b40ea73 %}

The `UsersModule` defines the single `UserEntity` to track in the database. It also provides and exports the `UserService` to be used by other modules as we will shortly see.

**Step 3**
Now that all entities are ready in the app, let’s generate a migration and run it against the database.

To generate a migration run the following command:
`yarn db:migration:generate -n InitialCreate`

This command generates the following migration file:
{% gist https://gist.github.com/bhaidar/2a9b26f5fa312e86f64da0a859e7c836 %}

The `up()` method creates two tables in the database: `movie` and `users`. Whereas, the `down()` method drops both tables.

Let’s run the migration against the database. Start by running the Postgres Docker container by running this command:
`yarn run:service`

Once the container is up and ready, run the following command to run the migration:
`yarn db:migrate`

The command runs the migrations against and the database and creates the table.

Now, I will create a new empty migration and seed a user record to use for testing purposes.

Run the following command to create an empty migration:
`yarn db:migration:create` -n SeedUserRecord

This command creates the following:
{% gist https://gist.github.com/bhaidar/ac38b7be467cf92f931619a36b3ce6d4 %}

Now add the code to the `up()` method to seed a user record:
{% gist https://gist.github.com/bhaidar/e473b9ed90d6bb64a8bf5a456b535807 %}

The code retrieves a repository instance for the `UserEntity`. It then creates and saves a user in the database.

To run the migration simply run this command: `yarn db:migrate`.

In addition, I will repeat the same steps to seed a few movie records. You can check the source code in the GitHub repo to see the migration there.

**Step 4**
Now that the database is ready, let's add the authentication module. 

![](https://thepracticaldev.s3.amazonaws.com/i/qx6usdjtizcoftikcxml.png)

The `auth.service.ts` file defines the authentication service as follows:
{% gist https://gist.github.com/bhaidar/f22999b1a70a6afd758acdd970394188 %}

This service contains the `validateUser()` method to validate the user and ensure the username and password provided by the client-side app matches those of the user stored in the database. 

Note that the code hashes the password received from the client-side app and compares it to the hashed password stored inside the database.

Also, the service contains the `login()` method that will be used later to return an access token based on the authenticated user. More to come on this later.

The `local.strategy.ts` file defines the Passport Local strategy used to validate a user via username and password by extending the base `PassportStrategy` class.
{% gist https://gist.github.com/bhaidar/9f746df77b6dbb58805d45ac45bbc7f5 %}

When it is time to run this strategy, @nestjs/passport calls the `validate()` method and passes in the username and password fields retrieved from the current HTTP Request. Internally, the method uses the `AuthService` to validate the user credentials. If the validation succeeds, the `validate()` method returns the user record. Otherwise, it returns null.

Based on the return value of the `validate()` method the request proceeds or fails.

The `jwt.strategy.ts` file defines the Passport JWT strategy used to verify that the JWT received from the client-side app is not expired and valid, extending the `PassportStrategy` class.
{% gist https://gist.github.com/bhaidar/3a6d345db25ec5f9479a5ce0d80cae99 %}

When extending the PassportStrategy class you have to call `super()` inside the constructor. You do so to instruct this strategy to read the JWT from the Authentication header of the request by looking at the Bearer token. In addition, it defines a secret key to use to decode the payload of the token. This same secret key is used to encrypt and sign the payload of the token and is defined in the `jwt.constants.ts` file as follows:

```
export const jwtConstants = {
  secret: 'v%re$1%3432F'
};
```

The `validate()` method in this strategy is only called once @nestjs/passport module verifies that the token is valid. It then calls this method providing it a valid decoded token. The method returns the User Id and the username fields. In this case, the request continues safely. Otherwise, if the token is invalid, the request is blocked and a `401 Unauthorized` response is sent back to the client-side app.

All strategies defined by Passport, store the result of  `validate()` method execution as a `user` property on the current HTTP Request object. You can customize the name of this property as you will see shortly.

Finally, the `auth,module,ts` file defines the `AuthModule` as follows:
{% gist https://gist.github.com/bhaidar/938c242a005284dfd0ddd2ec17105843 %}

It imports the `UsersModule`, the `PassportModule` and configures the latter by specifying the `defaultStrategy` and `property` name used to store the `validate()` results on the HTTP Request. It also exports the `AuthService` and all strategies so that they are imported by the root module of the app and made available.

**Step 5**
Import the `AuthModule` to the `AppModule` so that the authentication feature becomes available in the app.

Locate the `app.controller.ts` and add the login action as follows:
{% gist https://gist.github.com/bhaidar/392fbe84043ff87c4589428057b7dfb0 %}

The controller defines the `login()` action to allow the user to login to the app. Notice the user of `AuthGuard` in this case specifying the name of the Passport strategy to use? In our case the `local` strategy.

When the user hits the `/login` URL this action executes and the AuthGuard executes whatever strategy it is defined with. In this case, it loads the `LocalStrategy` and executes the `validate()` method passing to it the username and password the `login()` action method receives.

If the user is successfully validated against the credentials stored in the database, the body of the `login()` method executes. Inside the `login()` method the code calls the `authentication/Service.login()` method which in turn returns the access token to the client-side app.

> The authors behind the @nestjs/passport offer the same flexibility like that of Passport.js. By making the AuthGuard flexible, it accepts a strategy to execute when it is time to authenticate the user.

Let's import the `UsersModule` and `AuthModule` to the `AppModule`.

Finally, let's test this endpoint via Postman and see the results together:

![](https://thepracticaldev.s3.amazonaws.com/i/ezr4l67lfgfow7l465zl.png)

The payload of the request contains the user credentials. The payload of the response contains the access token. You may add more fields (user id, username, etc.) to the response of logging in to the app.

The backend authentication is ready. Let's move on and add an authentication module to the Angular app so that it can authenticate users against the backend.

##Adding authentication to the Angular app
Let's start by generating a new library by running this command:
`ng g @nrwl/angular:lib auth --directory="movietracker"`

The command generates a new `auth` module under the parent `movietracker` library folder.

![](https://thepracticaldev.s3.amazonaws.com/i/1ha67lqgjo3ppzikqs2j.png)

###Building the authentication service
The `authentication.service.ts` file defines the authentication service. You generate the service by running this command:
`ng g service services/authentication --project=movietracker-auth`

The service defines the `login()` method as:

{% gist https://gist.github.com/bhaidar/d96f93ef169fc02ca9c78614576ca4cd %}

The `login()` method uses the HttpClient class to send a POST request to the backend Web API Endpoint `/auth/login` with a request payload in the body containing the username and password of the user trying to login.

Upon a successful login, the token returned from the backend API is stored inside **LocalStorage** to be used on subsequent requests to send it over as a **Bearer** token authentication header.

As well, the `currentUserSubject` of type **BehaviorSubject** is triggered with the user payload. This subject is defined as follows inside the authentication service:

{% gist https://gist.github.com/bhaidar/cd8d7859aed307e50c85c06386a9ec2c %}

The `currentUserSubject` is defined as a BehaviorSubject with an initial value equal to whatever user is stored in the LocalStorage.

Also, the `currentUser` variable is defined as an Observable on top of the `currentUserSubject`. 

Other components and services in the application can now subscribe to the `currentUser` Observable since every time a successful login operation executes, it is guaranteed that this Observable will execute with the latest user signed in as a payload.

In addition, the `currentUserValue` is defined as a public getter to retrieve the value of the `currentUserSubject` variable. Later on we will use this value inside the Auth Guard as you will see shortly.

To logout a user, we simply delete the entry from the LocalStorage and populate the `currentUserSubject` with a null value signaling to all components and services that the user has signed out of the application.

Now let's amend the `apps/movietracker/proxy.conf.json` file as:
{% gist https://gist.github.com/bhaidar/f879b0806451de3c90b7420d2de54ea3 %}

I've added a new redirection for all URLs starting with `/auth` to simply redirect them to the URL where the backend is running and also remove `/auth` from the URL. For instance, when the Angular app requests the URL `http://localhost:4200/auth/login` the internal Webpack server, instructed by the `proxy.conf.json` will transform this request to `http://localhost:3000/login` to match the `login()` endpoint URL defined on the backend.

###Configure Routing
To restrict access to authenticated users only, let's define the following routing structure inside the `movietracker` app as follows:

{% gist https://gist.github.com/bhaidar/11906aaa27682b68672f9fbb1689190b %}

The default route now lives under `admin/movie-tracker`.

The path `/admin` now has a related component the `AppMainComponent`. This component renders an Angular Material layout for the entire application. 

In addition, any access to `/admin` is now restricted by the `AuthGuard` defined by implementing the `canActivate()` handler that is executed before navigating to the requested route.

The `movie-tracker` route is now defined as an admin child route.

A new route is added to route requests to the **Login**  component that we will build shortly.

The catch all route is added, so that if the user accesses any route that is not defined here, it redirects their request to the default route in the app.

Finally, the `movietracker/movies` library defines a single route as follows:
```typescript
const routes: Routes = [
  {
    path: '',
    component: MovieTrackerMoviesListComponent
  }
];
```

###AuthGuard details
Let's go back to the authentication module and go through the `AuthGuard`:
{% gist  https://gist.github.com/bhaidar/c2907dca310a722f7e3a49456c7852ca %}

You generate this guard by running this command:
`ng g guard guards/auth --project=movietracker-auth`

The `AuthGuard` implements the `CanActivate` interface and provides implementation for the `CanActivate()` handler. 

The handle calls the `authenticationService.currentUserValue` getter to check if there is an existing user stored in the LocalStorage. If there is one, the code returns true meaning that it is safe to allow the route navigation.

Otherwise, the user is redirected to the Login route. 

This `AuthGuard` is provided at the root of the application and hence it is accessible everywhere in the application.

All the services, guards and interceptors in the `AuthModule` are provided at the root module of the application and are available everywhere to all modules.

The `login.components.ts` file defines the Login component for the application:

![](https://thepracticaldev.s3.amazonaws.com/i/ea8lvct0754c68is85sn.PNG)

The component defines two form fields: username and password. It then communicates with the backend app through the `AuthenticationService` to login the user. You can refer to the source code of this component on GitHub [repo](https://github.com/bhaidar/movie-tracker/blob/add-authentication-server/libs/movietracker/auth/src/lib/containers/login.component.ts).

###Angular HTTP Interceptors
Moreover, two interceptors are defined in the `AuthModule`.

The `error.interceptor.ts` is defined to handle Unauthorized requests and redirect the user back to the Login page.

On the other hand, the `jwt.interceptor.ts` is defined to attach an access token to each request sent to the backend server whenever possible.

Both interceptor files export a **Provider** that can be provided by the root app module so that both interceptors are registered in the app.

```typescript
export const errorInterceptorProvider = {
  provide: HTTP_INTERCEPTORS,
  useClass: ErrorInterceptor,
  multi: true
};
```

Finally, we look at the `movietracker-auth.module.ts` file:
{% gist https://gist.github.com/bhaidar/b1fc7b9cb9838dca741fa04079cfb37d %}

It imports the `MovietrackerCoreModule`, declares and exports the `LoginComponent`. All other services in this module are automatically provided at the root app module.

###Running the app
Let's run the app by issuing the following commands:

```bash
yarn dev:server
yarn watch:movietracker
```

Let's try an invalid combination of a username and password and see how the Login component behaves.

![](https://thepracticaldev.s3.amazonaws.com/i/std7ypjrscdlpwy6eo3r.PNG)

Now let's try to sign in with the user credentials that we have previously seeded into the backend Web API and notice how the application now redirects us to the **Movie Tracker** route:

You are now redirected successfully. You can see the new UI layout and also click the **Logout** button whenever you want to sign out of the application. You may now continue managing your movies after you've signed in to the application.

![](https://thepracticaldev.s3.amazonaws.com/i/xk082pjp9br6ho0a44hq.png)

You may now try out all the functionality provided by the app for editing an existing movie, creating a new movie, deleting an existing movie and filtering out movies.

You can refer to the [previous article](https://dev.to/thisdotmedia/angular-and-the-rest-with-nest-js-2glo) to get more details on how these features work.

**Note**
You will notice that in the GitHub [repo](https://github.com/bhaidar/movie-tracker/tree/add-authentication-server) I've moved the `AuthenticationService` in the Angular app to the `api-services` library. Keeping all services that communicate with the backend in the same library is a good practice.

##Conclusion
This article ends the series on Angular and the REST. Now with knowledge at hand, you can make an informed decision. Either build a full stack app by using a single monorepo or two separate repos.

From my experience, using a monorepo makes life easier, is time efficient and more productive.

*This post was written by [Bilal Haidar](https://www.bhaidar.dev/), a mentor with [This Dot](https://thisdot.co/).*

*You can follow him on Twitter at @bhaidar.*

*Need JavaScript consulting, mentoring, or training help? Check out our list of services at [This Dot Labs](https://thisdot.co).*