Authentication and Sessions for MVC Apps with NestJS
Tags: nestjs, authentication, passport, nest
Published: 2019-07-22 14:29:22

*John is a member of the NestJS core team, primarily contributing to the documentation.*

**Note:** You can find all of the source code from this article [on github here](https://github.com/johnbiundo/mvc-sessions).

### Intro
There's a lot of good information on building API servers in [NestJS](https://github.com/nestjs/nest) (AKA Nest).  That use case is certainly a very strong fit for Nest.

Perhaps surprisingly, Nest is also very good at building traditional web applications - what Nest refers to as [MVC apps in the documentation](https://docs.nestjs.com/techniques/mvc).  By this I mean apps that you might otherwise consider building in ExpressJS + Handlebars, Laravel, or Ruby on Rails, with template-driven server-side rendering of pages.  Users considering Nest for this use case might find the resources in this area to be a little lighter than the API server use case.

This is probably partially due to the fact that most of the information you need to build say, an ExpressJS + Handlebars app, is already well covered and easy to find.  And most of that information applies directly to building such an app in Nest.  But leaving it at that still leaves a few questions for the Nest newcomer to sort out on their own.  This article attempts to provide a little more color on one aspect of the challenge: how to manage session-based authentication with Nest.  Why is this different with Nest?

Fully answering that question probably needs one or more complete articles on its own. The short answer is: if you really want to take advantage of Nest, it helps to try to learn to do things "the Nest way".  Nest makes no apologies for being opinionated.  It has a certain way of approaching application architecture.  If you're on-board with this approach, it helps to go all-in and try to build things the Nest way. This gives you amazing productivity advantages, helps you build [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) maintainable code, and lets you spend most of your time focusing on business logic, not boilerplate.  

The Nest way will be familiar to many coming from a Java or .NET background, as many of the concepts - such as OO and dependency injection - are similar.  But it should be equally accessible to anyone who has a background in `TypeScript`, `Angular`, or any modern FE or BE framework/enviroment.  As with any such framework, there's plenty of room for individual choice and style, but following the general patterns of the framework can make you feel like you have the wind at your back instead of swimming against the tide.

### Requirements

Phew!  With that out of the way, let's get a little more specific.  When it comes to the problem at hand, there are only a few Nest-specific techniques that you need to know to get a quick jump out of the starting blocks:

1. How to set up a template engine like [Handlebars](https://github.com/ericf/express-handlebars) to work with Nest
2. How to integrate template rendering with Nest controllers
3. How to integrate [express-session](https://github.com/expressjs/session) with Nest
4. How to integrate an authentication system (we'll specifically use [Passport](http://www.passportjs.org/)) with Nest

Items 3 and 4 are the main focus of this article.  To get there, we'll wade slightly into items 1 and 2 (providing code samples and references to Nest docs that can help you go deeper), but we won't spend a lot of time there.  Let me know in the comments if these are areas you'd like to see more about in future articles.

Let's take a quick look at the app we're going to build.
![App](https://thepracticaldev.s3.amazonaws.com/i/rk5x20yzmfmleusega2s.gif)

Our requirements are simple.  Users will authenticate with a username and password. Once authenticated, the server will use Express sessions so that the user remains "logged in" until they choose to log out. We'll set up a protected route that is accessible only to an authenticated user.

### Installation

If you haven't installed Nest before, the pre-requisites are simple.  You just need a modern Node.js environment (>=8.9 will do) and `npm` or `yarn`.  Then install Nest:
```bash
npm i -g @nestjs/cli
```

We start by installing the required packages, and building our basic routes.

Passport provides a library called [passport-local](https://github.com/jaredhanson/passport-local) that implements a username/password *authentication strategy*, which suits our needs for this use case. Since we are rendering some basic HTML pages, we'll also install the versatile and popular [express-handlebars](https://github.com/ericf/express-handlebars) package to make that a little easier.  To support sessions and to provide a convenient way to give user feedback during login, we'll also utilize the `express-session` and `connect-flash` packages. 

> **Note** For **any** Passport strategy you choose (there are many available [here](http://www.passportjs.org)), you'll always need the `@nestjs/passport` and `passport` packages. Then, you'll need to install the strategy-specific package (e.g., `passport-jwt` or `passport-local`) that scaffolds the particular authentication strategy you are building.

With these basic requirements in mind, we can now start by scaffolding a new Nest application, and installing the dependencies:

```bash
nest new mvc-sessions
cd mvc-sessions
npm install --save @nestjs/passport passport passport-local express-handlebars express-session connect-flash 
npm install --save-dev @types/express @types/express-session @types/connect-flash @types/express-handlebars
```

### Web interface

Let's start by building the templates we'll use for the UI of our authentication subsystem.  Following a standard MVC type project structure, create the following folder structure (i.e., the `public` folder and its sub-folders):
```
mvc-sessions
└───public
│   └───views
│       └───layouts
```

Now create the following handlebars templates, and configure Nest to use express-handlebars as the view engine.  Refer [here for more on the handlebars template language](https://handlebarsjs.com/) , and [here for more background on Nest-specific techniques](https://docs.nestjs.com/techniques/mvc)  for server-side rendered (MVC style) web apps.

#### Main layout

Create `main.hbs` in the layouts folder, and add the following code.  This is the outermost container for our views.  Note the `{{{ body }}}` line, which is where each individual view is inserted.  This structure allows us to set up global styles.  In this case, we're taking advantage of Google's widely used [material design lite](https://github.com/google/material-design-lite) component library to style our minimal UI. All of those dependencies are taken care of in the `<head>` section of our layout.

```html
<!-- public/views/layouts/main.hbs -->
<!DOCTYPE html>
<html>
  <head>
    <script src="https://code.getmdl.io/1.3.0/material.min.js"></script>
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
    <link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
    <style>
      .mdl-layout__content {
        padding: 24px;
        flex: none;
      }
      .mdl-textfield__error {
        visibility: visible;
        padding: 5px;
      }
      .mdl-card {
        padding-bottom: 10px;
        min-width: 500px;
      }
    </style>
  </head>
  <body>
    {{{ body }}}
  </body>
</html>
```

#### Home page

Create `home.hbs` in the `views` folder, and add the following code.  This is the page users land on after authenticating.
```html
<!-- public/views/home.hbs -->
<div class="mdl-layout mdl-js-layout mdl-color--grey-100">
  <main class="mdl-layout__content">
    <div class="mdl-card mdl-shadow--6dp">
      <div class="mdl-card__title mdl-color--primary mdl-color-text--white">
        <h2 class="mdl-card__title-text">Welcome {{ user.username }}!</h2>
      </div>
      <div class="mdl-card__supporting-text">
        <div class="mdl-card__actions mdl-card--border">
          <a class="mdl-button" href='/profile'>GetProfile</a>
        </div>
      </div>
    </div>
  </main>
</div>
```
#### Login page

Create `login.hbs` in the `views` folder, and add the following code.  This is the login form.
```html
<!-- public/views/login.hbs -->
<div class="mdl-layout mdl-js-layout mdl-color--grey-100">
  <main class="mdl-layout__content">
    <div class="mdl-card mdl-shadow--6dp">
      <div class="mdl-card__title mdl-color--primary mdl-color-text--white">
        <h2 class="mdl-card__title-text">Nest Cats</h2>
      </div>
      <div class="mdl-card__supporting-text">
        <form action="/login" method="post">
          <div class="mdl-textfield mdl-js-textfield">
            <input class="mdl-textfield__input" type="text" name="username" id="username" />
            <label class="mdl-textfield__label" for="username">Username</label>
          </div>
          <div class="mdl-textfield mdl-js-textfield">
            <input class="mdl-textfield__input" type="password" name="password" id="password" />
            <label class="mdl-textfield__label" for="password">Password</label>
          </div>
          <div class="mdl-card__actions mdl-card--border">
            <button class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">Log In</button>
            <span class="mdl-textfield__error">{{ message }}</span>
          </div>
        </form>
      </div>
    </div>
  </main>
</div>
```
#### Profile page

Create `profile.hbs` in the `views` folder and add the following code.  This page displays details about the logged in user.  It's rendered on our protected route.
```html
<!-- public/views/profile.hbs -->
<div class="mdl-layout mdl-js-layout mdl-color--grey-100">
  <main class="mdl-layout__content">
    <div class="mdl-card mdl-shadow--6dp">
      <div class="mdl-card__title mdl-color--primary mdl-color-text--white">
        <h2 class="mdl-card__title-text">About {{ user.username }}</h2>
      </div>
      <div>
        <figure><img src="http://lorempixel.com/400/200/cats/{{ user.pet.picId }}">
          <figcaption>{{ user.username }}'s friend {{ user.pet.name }}</figcaption>
        </figure>
        <div class="mdl-card__actions mdl-card--border">
          <a class="mdl-button" href='/logout'>Log Out</a>
        </div>
      </div>
    </div>
  </main>
</div>
```

#### Set up view engine

Now we tell Nest to use express-handlebars as the view engine.  We do this in the `main.ts` file, which by convention is where your Nest app will be bootstrapped from.  While we won't go into a lot of detail here, the main concepts are:
1. Pass the `<NestExpressApplication>` type assertion in the `NestFactory.create()`  method call to gain access to native Express methods.
2. Having done that, you can now simply access any of Express's native `app` methods.  For the most part, the configuration of the view engine, and any other traditional Express middleware, proceeds as normal as with the view engine setup shown below.

Modify the `main.ts` file so that it looks like this:
```typescript
// src/main.ts
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { AppModule } from './app.module';
import * as exphbs from 'express-handlebars';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  const viewsPath = join(__dirname, '../public/views');
  app.engine('.hbs', exphbs({ extname: '.hbs', defaultLayout: 'main' }));
  app.set('views', viewsPath);
  app.set('view engine', '.hbs');

  await app.listen(3000);
}
bootstrap();
```

### Authentication routes
The final step in this section is setting up our routes.  This is one area where the MVC architecture starts to shine through.  It can be a little unfamiliar if you're used to bare Express routes, so let's wade in a little.  Feel free to take a few minutes to read the [Nest documentation on controllers](https://docs.nestjs.com/controllers) for lots more details on how Nest Controllers work.

We'll modify `app.controller.ts` so that it looks like the large code block below.  

Before we do that, let's take a moment to look at the `GET /` route handler in the large code block below (the line starting with `@Get('/')`.  The work is done by the `@Render()` decorator.  Since all we're doing in this first iteration of the code is rendering our templates, the code is trivial.  `@Render()` takes a single argument, which is the name of the template to render.  Think of this as the Nest equivalent of Express code like:
```javascript
app.get('/', function (req, res) {
    res.render('login');
});
```

Methods decorated with `@Render()` can also return a value that will supply template variables.  For now, we'll just do an empty return (implicitly returning `undefined`).  Later, we'll use this feature to pass template variables.  

Go ahead and update `src/app.controller.ts` with this code:

```typescript
// src/app.controller.ts
import { Controller, Get, Post, Res, Render } from '@nestjs/common';
import { Response } from 'express';

@Controller()
export class AppController {
  @Get('/')
  @Render('login')
  index() {
    return;
  }

  @Post('/login')
  login(@Res() res: Response): void {
    res.redirect('/home');
  }

  @Get('/home')
  @Render('home')
  getHome() {
    return;
  }

  @Get('/profile')
  @Render('profile')
  getProfile() {
    return;
  }

  @Get('/logout')
  logout(@Res() res: Response): void {
    res.redirect('/');
  }
}
```

At this point, you should be able to run the app:
```bash
$ npm run start
```
Now, browse to [http://localhost:3000](http://localhost:3000) and click through the basic UI.  At this point, of course, you can click through the pages without logging in.


### Implementing Passport strategies

We're now ready to implement the authentication feature. It's helpful to have a good understanding of how Nest integrates with Passport.  The Nest docs [covers this in some depth](https://docs.nestjs.com/techniques/authentication#implementing-passport-strategies).  It's worth taking a quick detour to read that section.  

> Note: I authored that section of the NestJS docs, so you'll see some similarities/overlaps with the code and documentation below

The key takeaways are:
1. Nest provides the `@nestjs/passport` module which *wraps* Passport in a Nest style package that makes it easy to treat Passport as a [*provider*](https://docs.nestjs.com/providers).
2. You implement Passport *strategies* by extending the `PassportStrategy` class, where you implement the strategy-specific initialization and callback.

As mentioned, we'll utilize the passport-local strategy for this use case.  We'll get to that implementation in a moment.  Start by generating an `AuthModule` and in it, an `AuthService`:

```bash
nest g module auth
nest g service auth
```

We'll also implement a `UsersService` to manage our *User store*, so we'll generate that module and service now:

```bash
nest g module users
nest g service users
```

Replace the default contents of these generated files as shown below.  For our sample app, the `UsersService` simply maintains a hard-coded in-memory list of users, and a method to retrieve one by username.  In a real app, this is where you'd build your user model and persistence layer, using your library of choice (e.g., TypeORM, Sequelize, Mongoose, etc.).

```typescript
// src/users/users.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  private readonly users: any[];

  constructor() {
    this.users = [
      {
        userId: 1,
        username: 'john',
        password: 'changeme',
        pet: { name: 'alfred', picId: 1 },
      },
      {
        userId: 2,
        username: 'chris',
        password: 'secret',
        pet: { name: 'gopher', picId: 2 },
      },
      {
        userId: 3,
        username: 'maria',
        password: 'guess',
        pet: { name: 'jenny', picId: 3 },
      },
    ];
  }

  async findOne(username: string): Promise<any> {
    return this.users.find(user => user.username === username);
  }
}
```

In the `UsersModule`, the only change is to add the `UsersService` to the exports array of the `@Module` decorator so that it is visible outside this module (we'll soon use it in our `AuthService`).  
You can [read more here about how Nest uses modules](https://docs.nestjs.com/modules) to organize code and to understand more about the `exports` array and other parameters of the `@Module()` decorator.

Make sure `src/users/users.module.ts` looks like this:

```typescript
// src/users/users.module.ts
import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

Our `AuthService` has the job of retrieving a user and verifying the password.  Replace the default contents of the `src/auth/auth.service.ts` file with the code below:

```typescript
// src/auth/auth.service.ts
import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(private readonly usersService: UsersService) {}

  async validateUser(username, pass): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }
}
```

> **Warning** Of course in a real application, you wouldn't store a password in plain text. You'd instead use a library like [bcrypt](https://github.com/kelektiv/node.bcrypt.js#readme), with a salted one-way hash algorithm. With that approach, you'd only store hashed passwords, and then compare the stored password to a hashed version of the **incoming** password, thus never storing or exposing user passwords in plain text. To keep our sample app simple, we violate that absolute mandate and use plain text.  **Don't do this in your real app!**

We'll call into our `validateUser()` method from our passport-local strategy subclass in a moment. The Passport library expects us to return a full user if the validation succeeds, or a null if it fails (failure is defined as either the user is not found, or the password does not match). In our code, we use a convenient ES6 spread operator to strip the password property from the user object before returning it. Upon successful validation, Passport then takes care of a few details for us, which we'll explore later on in the Sessions section.

And finally, we update our `AuthModule` to import the `UsersModule`.

```typescript
// src/auth/auth.module.ts
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
})
export class AuthModule {}
```

Our app will function now, but remains incomplete until we finish a few more steps.  You can restart the app and navigate to [http://localhost:3000](http://localhost:3000) and still move around without logging in (after all, we haven't implemented our passport-local strategy yet.  We'll get there momentarily). 

#### Implementing Passport local

Now we can implement our passport-local strategy.  Create a file called `local.strategy.ts` in the `auth` folder, and add the following code:

```typescript
// src/auth/local.strategy.ts
import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly authService: AuthService) {
    super();
  }

  async validate(username: string, password: string) {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

We've followed the recipe described in the [NestJS Authentication Chapter](https://docs.nestjs.com/techniques/authentication#implementing-passport-strategies).  In this use case with passport-local, there are no configuration options, so our constructor simply calls `super()`, without an options object.

We've also implemented the `validate()` method. For the local-strategy, Passport expects a `validate()` method with a signature like

```
validate(username: string, password:string): any
```

Most of the work is done in our `AuthService` (and in turn, in our `UserService`), so this method is quite straightforward. The `validate()` method for **any** Passport strategy will follow a similar pattern.  If a user is found and valid, it's returned so request handling can continue, and Passport can do some further housekeeping.  If it's not found, we throw an exception and let [Nest's exceptions layer](https://docs.nestjs.com/exceptions) handle it.

With the strategy in place, we have a few more tasks to complete:
1. Create guards used to decorate routes so that the configured Passport strategy is invoked
2. Add `@UseGuards()` decorators as needed
3. Implement sessions so that users stay logged in across requests
4. Configure Nest to use Passport and session-related features
5. Add a little polish to the user experience

Let's get started.  For the following sections, we'll want to adhere to a best practice project structure, so start by creating a few more folders.  Under `src`, create a `common` folder.  Inside `common`, create `filters` and `guards` folders.  Our project structure now looks like this:
```
mvc-sessions
└───src
│   └───auth
│   └───common
│       └───filters
│       └───guards
│   └───users
└───public
```

### Implement guards

The NestJS [Guards chapter](https://docs.nestjs.com/guards) describes the primary function of guards: to determine whether a request will be handled by the route handler or not.  That remains true, and we'll use that feature soon.  However, in the context of using the `@nestjs/passport` module, we will also introduce a slight new wrinkle that may at first be confusing, so let's discuss that now. Once again, the NestJS Authentication chapter has a [section which describes this scenario](https://docs.nestjs.com/techniques/authentication#built-in-passport-guards) which would be good to read now.  The key takeaways are:
1. Passport supports authentication in two *modes*.  First, you need to perform the authentication step (i.e., *logging in*)
2. Subsequently, you need to *verify a user's credentials*.  In the case of passport-local, this means ensuring that the user's session is valid.

**Both** of these steps are implemented via Nest **guards**.  

#### Initial Authentication
Looking at our UI, it's easy to see that we'll handle this initial authentication step via a `POST` request on our `/login` route. So how do we invoke the "login phase" of the passport-local strategy in that route? As suggested, the answer is to use a Guard.  Similar to the way we extended the `PassportStrategy` class in the last section, we'll start with a default `AuthGuard` provided in the `@nestjs/passport` package, and extend it as needed. We'll name our new Guard `LoginGuard`.  We'll then decorate our `POST /login` route with this `LoginGuard` to invoke the login phase of our passport-local strategy.

Create a file called `login.guard.ts` in the `guards` folder and replace its default contents as follows:

```typescript
// src/common/guards/login.guard.ts
import { ExecutionContext, Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class LoginGuard extends AuthGuard('local') {
  async canActivate(context: ExecutionContext) {
    const result = (await super.canActivate(context)) as boolean;
    const request = context.switchToHttp().getRequest();
    await super.logIn(request);
    return result;
  }
}
```

There's a lot going on in these few lines of code, so let's walk through it.
- Our passport-local strategy has a default name of 'local'.  We reference that name in the `extends` clause of the `LoginGuard` we are defining in order to tie our custom guard to the code supplied by the `passport-local` package. This is needed to disambiguate which class we are extending in case we end up using multiple Passport strategies in our app (each of which may contribute a strategy-specific `AuthGuard`).
- As with all guards, the primary method we define/override is `canActivate()`, which is what we do here.  You can read more about [guards and customizing the `canActivate()` method here](https://docs.nestjs.com/guards).
- The critical part happens in the body of `canActivate()` , where we set up an Express session.  Here's what's happening:
    - We call `canActivate()` on the super class, as we normally would in extending a class method. Our super class provides the framework for invoking our passport-local strategy.  Recall from the [Guards](https://docs.nestjs.com/guards) chapter that `canActivate()` returns a boolean indicating whether or not the target route will be called.  When we get here, Passport will have run the previously configured strategy (from the super class) and will return a boolean to indicate whether or not the user has successfully authenticated.  Here, we stash the result so we can do a little more processing before finally returning from our method.
    - The key step for starting a session is to now invoke the `logIn()` method on our super class, passing in the current request.  This actually calls a special method that Passport automatically added to our Express `Request` object during the previous step.  See [here](http://www.passportjs.org/docs/configure/) and [here](http://www.passportjs.org/docs/login/) for more on Passport sessions and these special methods.
    - The Express session has now been set up, and we can return our `canActivate()` result, allowing only authenticated users to continue.

### Sessions

Now that we've introduced sessions, there's one additional detail we need to take care of.  Sessions are a way of associating a unique user with some server-side state information about that user.  Let's delve briefly into how Passport rides on top of Express sessions to provide some context.

Passport adds properties to the `session` object to keep track of information about the user and their authentication state.  The user details are populated by a `serializeUser()` call to the Passport library.  This function is called automatically by Nest with the `user` object created in the `validate()` method (which we implemented in  `src/auth/local.strategy.ts` a few minutes ago).  This approach may feel a little complex at first, but it supports a completely flexible model for how you can manage interactions with your *User store*.  In our case, we are simply passing the `user` object through untouched.  In advanced scenarios, you may find yourself calling out to your database or caching layer to augment the user object with more information (e.g., roles/permissions).  Unless you're doing something advanced like that, you can usually just use the following boilerplate for the serialization process.

Create the `session.serializer.ts` file in the `auth` folder, and add the following code:
```typescript
// src/auth/session.serializer.ts
import { PassportSerializer } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
@Injectable()
export class SessionSerializer extends PassportSerializer {
  serializeUser(user: any, done: (err: Error, user: any) => void): any {
    done(null, user);
  }
  deserializeUser(payload: any, done: (err: Error, payload: string) => void): any {
    done(null, payload);
  }
}
```

We need to configure our `AuthModule` to use the Passport features we just defined.  Of course `AuthService` and `LocalStrategy` make sense as *providers* (read [more about providers here](https://docs.nestjs.com/providers) if you need to).  Note that the `SessionSerializer` we just created is also a pluggable provider, and needs to be included in the `providers` array. Don't worry if this isn't 100% clear at the moment. Just think of *providers* as a generic way to inject customizable services into your application structure (including 3rd party modules you've included).  

Update `auth.module.ts` to look like this:
```typescript
// src/auth/auth.module.ts
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';
import { SessionSerializer } from './session.serializer';

@Module({
  imports: [UsersModule, PassportModule],
  providers: [AuthService, LocalStrategy, SessionSerializer],
})
export class AuthModule {}
```

Now let's create our `AuthenticatedGuard`.  This is a traditional guard, as covered in the NestJS [Guards chapter](https://docs.nestjs.com/guards). Its role is simply to protect certain routes. Create the file `authenticated.guard.ts` in the `guards` folder, and add the following code:

```typescript
// src/common/guards/authenticated.guard.ts
import { ExecutionContext, Injectable, CanActivate } from '@nestjs/common';

@Injectable()
export class AuthenticatedGuard implements CanActivate {
  async canActivate(context: ExecutionContext) {
    const request = context.switchToHttp().getRequest();
    return request.isAuthenticated();
  }
}
```

The only thing to point out here is that in order to determine whether a user is authenticated or not, we use the convenient `isAuthenticated()` method that Passport has attached to the `request` object for us.  Passport will return `true` only if the user is authenticated (i.e., has a valid session).

### Configure Nest to bootstrap features

We can now tell Nest to use the Passport features we've configured.  Update `main.ts` to look like this:

```typescript
// src/main.ts
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { AppModule } from './app.module';

import * as session from 'express-session';
import flash = require('connect-flash');
import * as exphbs from 'express-handlebars';
import * as passport from 'passport';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);

  const viewsPath = join(__dirname, '../public/views');
  app.engine('.hbs', exphbs({ extname: '.hbs', defaultLayout: 'main' }));
  app.set('views', viewsPath);
  app.set('view engine', '.hbs');

  app.use(
    session({
      secret: 'nest cats',
      resave: false,
      saveUninitialized: false,
    }),
  );

  app.use(passport.initialize());
  app.use(passport.session());
  app.use(flash());

  await app.listen(3000);
}
bootstrap();
```

Here, we've added the session and Passport support to our Nest app.

> **Warning** As always, be sure to keep secrets out of your source code (**don't put your session secret in the code, as we did here; use environment variables or a config module (such as [NestJS Config Manager](https://github.com/nestjsplus/config) instead**).

Note carefully that the order is important (register the session middleware first, then initialize Passport, then configure Passport to use sessions).  We'll see the use of the `flash` feature in a few minutes.

#### Add route guards

Now we're ready to start applying these guards to routes.  Update `app.controller.ts` to look like this:

```typescript
// src/app.controller.ts
import { Controller, Get, Post, Request, Res, Render, UseGuards } from '@nestjs/common';
import { Response } from 'express';

import { LoginGuard } from './common/guards/login.guard';
import { AuthenticatedGuard } from './common/guards/authenticated.guard';

@Controller()
export class AppController {
  @Get('/')
  @Render('login')
  index() {
    return;
  }

  @UseGuards(LoginGuard)
  @Post('/login')
  login(@Res() res: Response) {
    res.redirect('/home');
  }

  @UseGuards(AuthenticatedGuard)
  @Get('/home')
  @Render('home')
  getHome(@Request() req) {
    return { user: req.user };
  }

  @UseGuards(AuthenticatedGuard)
  @Get('/profile')
  @Render('profile')
  getProfile(@Request() req) {
    return { user: req.user };
  }

  @Get('/logout')
  logout(@Request() req, @Res() res: Response) {
    req.logout();
    res.redirect('/');
  }
}
```

Above, we've imported our two new guards and applied them appropriately.  We use the `LoginGuard` on our `POST /login` route to initiate the authentication sequence in the passport-local strategy.  We use `AuthenticatedGuard` on our protected routes to ensure they aren't accessible to unauthenticated users.

We're also taking advantage of the Passport feature that automatically stores our `User` object on the `Request` object as `req.user`.  With this handy feature, we can now return values on our routes decorated with `@Render()` to pass a variable into our handlebars templates to customize their content.
For example  `return { user: req.user }` to display information from the `User` object in our `home` template.

Finally, we have added the call to `req.logout()` in our `logout` route.  This relies on the Passport `logout()` function, which, like the `logIn()` method we discussed earlier in the Sessions section, has been added to the Express `Request` object by Passport automatically upon successful authentication.  When we invoke `logout()`, Passport tears down our session for us.

You should now be able to test the authentication logic by attempting to navigate to a protected route.  Restart the app and point your browser at [http://localhost:3000/profile](http://localhost:3000/profile).  You should get a `403 Forbidden` error.  Return to the root page at [http://localhost:3000](http://localhost:3000), and log in, and you should be able to browse around (though the app is still missing a couple of features).  Refer to `src/users/users.service.ts` for the hard-coded usernames and passwords that are accepted.

### Adding polish
Let's address that ugly 403 Forbidden error page. If you navigate around the app, trying things like submitting an empty login request, a bad password, and logging out, you'll see that it's not a very good UX.  Let's take care of a couple of things:
1. Let's send the user back to the login page whenever they fail to authenticate, and when they log out of the app
2. Let's provide a little feedback when a user types in an incorrect password

The best way to handle the first requirement is to implement a [Filter](https://docs.nestjs.com/exception-filters).  Create the file `auth-exceptions.filter.ts` in the `filters` folder, and add the following code:

```typescript
// src/common/filters/auth-exceptions.filter.ts
import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
  UnauthorizedException,
  ForbiddenException,
} from '@nestjs/common';
import { Request, Response } from 'express';

@Catch(HttpException)
export class AuthExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();

    if (
      exception instanceof UnauthorizedException ||
      exception instanceof ForbiddenException
    ) {
      request.flash('loginError', 'Please try again!');
      response.redirect('/');
    } else {
      response.redirect('/error');
    }
  }
}
```

The only new element here from what's covered in the NestJS [Filters chapter](https://docs.nestjs.com/exception-filters) is the use of `connect-flash`.  If a route returns either an `UnauthorizedException` or a `ForbiddenException`, we redirect to the root route with `response.redirect('/')`.  We also use `connect-flash` to store a message in Passport's session.  This mechanism allows us to temporarily persist a message upon redirect.  Passport and `connect-flash` automatically take care of the details of storing, retrieving, and cleaning up those messages.

The final touch is to display the flash message in our handlebars template.  Update `app.controller.ts` to look like this.  In this update, we're adding the `AuthExceptionFilter` and adding the flash parameters to our index (`/`) route.

```typescript
// src/app.controller.ts
import { Controller, Get, Post, Request, Res, Render, UseGuards, UseFilters } from '@nestjs/common';
import { Response } from 'express';

import { LoginGuard } from './common/guards/login.guard';
import { AuthenticatedGuard } from './common/guards/authenticated.guard';
import { AuthExceptionFilter } from './common/filters/auth-exceptions.filter';

@Controller()
@UseFilters(AuthExceptionFilter)

export class AppController {
  @Get('/')
  @Render('login')
  index(@Request() req): { message: string } {
    return { message: req.flash('loginError') };
  }

  @UseGuards(LoginGuard)
  @Post('/login')
  login(@Res() res: Response) {
    res.redirect('/home');
  }

  @UseGuards(AuthenticatedGuard)
  @Get('/home')
  @Render('home')
  getHome(@Request() req) {
    return { user: req.user };
  }

  @UseGuards(AuthenticatedGuard)
  @Get('/profile')
  @Render('profile')
  getProfile(@Request() req) {
    return { user: req.user };
  }

  @Get('/logout')
  logout(@Request() req, @Res() res: Response) {
    req.logout();
    res.redirect('/');
  }
}
```

We now have a fully functional authentication system for our server side Web application.  Go ahead and fire it up and [try logging in](http://localhost:3000) and out, accessing protected routes while logged out, and typing bad/missing username/password fields, and notice the more friendly error handling.

We're done! Kudo's for hanging in through a **long** tutorial.  I hope this helps you understand some techniques for implementing sessions and authentication with NestJS.

### Resources

You can find all of the source code from this article [on github here](https://github.com/johnbiundo/mvc-sessions).

Feel free to ask questions, make comments or suggestions, or just say hello in the comments below.  And join us at [Discord](https://discord.gg/G7Qnnhy) for more happy discussions about NestJS.  I post there as *Y Prospect*.

### Acknowledgements
Thanks to [Jay McDoniel](https://github.com/jmcdo29), [Livio Brunner](https://github.com/BrunnerLivio) and [Kamil Myśliwiec](https://github.com/kamilmysliwiec) for their help reviewing this article.