> 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/rate-limiting.md).

# Rate limiting

A way to avoid too many requests at once from a single source.

If a malicious person wishes, they can bombard our server with requests, throttling it. Fortunately, it's quite simple to avoid this kind of situation. Nest has integration with a **Throttler**, which limits the amount of requests that a route may receive in a time interval from the same source. This process is called **Rate Limiting**.

First, we should install it.

```sh
yarn add @nestjs/throttler
```

Then, create variables in <mark style="color:purple;">.env</mark> and <mark style="color:purple;">.env.example</mark> to store the options we'll use for the throttler.

```properties
THROTTLER_TTL = 60
THROTTLER_LIMIT = 10
```

With this, when a request arrives, it is "remembered" for the time defined in **TTL**. If the amount of requests from the same source reaches the value of **LIMIT**, no more requests will be accepted until old ones are "forgotten" first. Roughly speaking, this means that, in each route, for a time interval of 60 seconds, only 10 requests from the same source will be accepted.

Proceeding, add them to the validation schema accordingly.

```typescript
Joi.number().integer().positive().required(),
```

Finally, create its **configuration namespace** in <mark style="color:purple;">auth</mark> -> <mark style="color:purple;">config</mark> -> <mark style="color:purple;">throttler.config</mark>.

```typescript
export default registerAs('throttler', () => {
  const config = [
    {
      ttl: seconds(+process.env.THROTTLER_TTL),
      limit: +process.env.THROTTLER_LIMIT,
    },
  ] as const satisfies ThrottlerModuleOptions;
  return config;
});
```

{% hint style="info" %}
Note that:

* The variables must be cast to <mark style="color:blue;">number</mark>, as they are <mark style="color:blue;">strings</mark>
* The <mark style="color:blue;">`ttl`</mark> is converted from **seconds** to **ms** (the used format)
* The options object should be put inside an array
  {% endhint %}

Then, in the <mark style="color:blue;">`imports`</mark> of the <mark style="color:blue;">`AuthModule`</mark>, we can add the <mark style="color:blue;">`ThrottlerModule`</mark>.

```typescript
ThrottlerModule.forRootAsync(throttlerConfig.asProvider()),
```

After this, in the <mark style="color:blue;">`providers`</mark> of the <mark style="color:blue;">`AuthModule`</mark>, we can enable the <mark style="color:blue;">`ThrottlerGuard`</mark> globally, <mark style="color:red;">**before**</mark> the other guards.

```typescript
{
  provide: APP_GUARD,
  useClass: ThrottlerGuard,
},
```

{% hint style="danger" %}
The intention of the throttler is to prevent excessive usage of resources. If used after the other guards, it would not activate when accessing a protected route with and invalid token, for example, which would consume resources to check the user's identity.
{% endhint %}

{% hint style="warning" %}
Unfortunately, the throttler <mark style="color:red;">won't</mark> work in the <mark style="color:blue;">`login()`</mark> route due to the **middleware**, as it fails first and **stops** the request lifecycle before its activation. We could:

* Leave it as it is, as the credentials validation is not so expensive
* Simply disable the middleware, not enforcing validation on the credentials anymore
* Enforce this validation inside the <mark style="color:blue;">`LocalAuthGuard`</mark>
  {% endhint %}

{% hint style="info" %}
We can also have finer control over this process if desired, using decorators that change a specific behavior for a certain route or controller. For example:

* <mark style="color:blue;">`@SkipThrottle()`</mark> - Disables the throttler (may receive <mark style="color:blue;">false</mark> to not disable it)
* <mark style="color:blue;">`@Throttle()`</mark> - Overrides the values of <mark style="color:blue;">`ttl`</mark> and <mark style="color:blue;">`limit`</mark>
  {% endhint %}

<mark style="color:green;">**Commit**</mark> - Using rate limiting to protect against brute force attacks
