> For the complete documentation index, see [llms.txt](https://kinesis-school-of-programming.gitbook.io/nestjs-unleashed/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kinesis-school-of-programming.gitbook.io/nestjs-unleashed/extra-module-1-authentication-authorization/authentication/validation-middleware.md).

# Validation middleware

We may resort to a middleware when we cannot have automatic validation.

If you have noticed, we are <mark style="color:red;">not</mark> validating the login credentials in a DTO before we actually check if a <mark style="color:blue;">`user`</mark> with that <mark style="color:blue;">`email`</mark> exists and the <mark style="color:blue;">`password`</mark> is correct. In this case, we unfortunately cannot use the <mark style="color:blue;">`@Body()`</mark> decorator to validate the login credentials because **guards are activated before pipes**, and therefore the <mark style="color:blue;">`LocalAuthGuard`</mark> is activated before the <mark style="color:blue;">`ValidationPipe`</mark>. A solution we can use, although not as tidy as just using a DTO directly with the <mark style="color:blue;">`@Body()`</mark> decorator, is to use a **Middleware**, which is the only thing that is activated before a guard. Let's then begin.

> The official NestJS doc about [Request lifecycle](https://docs.nestjs.com/faq/request-lifecycle) better explains this execution order.

First, we will actually create a DTO for the login credentials. Create then, the file <mark style="color:purple;">auth</mark>/<mark style="color:purple;">dto</mark>/<mark style="color:purple;">login.dto</mark> with the respective validation.

```typescript
@IsEmail()
readonly email: string;

@IsPassword()
readonly password: string;
```

Another approach we could use, is to make the <mark style="color:blue;">`LoginDto`</mark> be a <mark style="color:blue;">`PickType`</mark> of the <mark style="color:blue;">`CreateUserDto`</mark>, as the fields with their respective validations are already there. It may be a bit cleaner but maybe also a bit more coupled solution. The decision is left to the reader.

```typescript
export class LoginDto extends PickType(CreateUserDto, ['email', 'password'] as const) {}
```

After that, let's create the **middleware**.

```sh
nest g mi auth/middleware/login-validation
```

{% hint style="info" %}
Remember to replace the types of the parameters with <mark style="color:blue;">`Request`</mark>, <mark style="color:blue;">`Response`</mark> and <mark style="color:blue;">`NextFunction`</mark> from <mark style="color:blue;">`express`</mark>.
{% endhint %}

Inside the <mark style="color:blue;">`use()`</mark> method, first we'll transform the <mark style="color:blue;">`req.body`</mark> into an instance of the <mark style="color:blue;">`LoginDto`</mark>.

```typescript
const loginDto = plainToInstance(LoginDto, req.body);
```

Then, we'll manually use the <mark style="color:blue;">`validate()`</mark> method from **class-validator** to obtain potential errors from the validation of the <mark style="color:blue;">`loginDto`</mark>. Notice that we also use options to ensure that no strange fields will be accepted.

```typescript
const errors = await validate(loginDto, {
  whitelist: true,
  forbidNonWhitelisted: true,
});
```

Then, if there are errors, we send their messages in a <mark style="color:blue;">`BadRequestException`</mark>. We want to obtain **only the values** (<mark style="color:blue;">`Object.values()`</mark>) from the <mark style="color:blue;">`constraints`</mark> field, and then merge the resulting arrays into a single array with the error messages (<mark style="color:blue;">`flatMap()`</mark>).

```typescript
if (errors.length) {
  const errorMessages = errors.flatMap((error) =>
    Object.values(error.constraints),
  );
  throw new BadRequestException(errorMessages);
}
```

All right, we have our <mark style="color:blue;">`LoginValidationMiddleware`</mark>. To use it, we need to go to the <mark style="color:blue;">`AuthModule`</mark>. First, make it implement the <mark style="color:blue;">`NestModule`</mark> interface. Then, inside the class, implement the <mark style="color:blue;">`configure()`</mark> method, which receives a <mark style="color:blue;">`MiddlewareConsumer`</mark>. Make the <mark style="color:blue;">`consumer`</mark> call the <mark style="color:blue;">`apply()`</mark> method with the middleware to be used. Then, chain this with a call to the <mark style="color:blue;">`forRoutes()`</mark> method, with the path to the route that will receive the middleware.

```typescript
export class AuthModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoginValidationMiddleware).forRoutes('auth/login');
  }
}
```

And there we have it, our fields are being validated.

<mark style="color:green;">**Commit**</mark> - Validating login credentials with middleware

An improvement that could be done, is to create a generic <mark style="color:blue;">`ValidationMiddleware`</mark> factory function that would have a DTO class as parameter, and return a validation middleware class responsible for validating that specific DTO. To achieve this, we should create a function that has a type parameter that extends the <mark style="color:blue;">`Type`</mark> from NestJS (which represents a class), and a parameter of its type. After that, return the middleware class as it was, altering just the argument of <mark style="color:blue;">`validate()`</mark> accordingly.

```typescript
export const ValidationMiddleware = <TDto extends Type>(DtoClass: TDto) => {
  // Class goes here
}
```

We should also remember to rename the file itself and also the folder.

<mark style="color:green;">**Commit**</mark> - Generic middleware with factory function
