Nodejs Nestjs限流插件nestjs-rate-limiter的使用

Nodejs Nestjs限流插件nestjs-rate-limiter的使用
nestjs-rate-limiter 是一个用于 NestJS 的限流插件,可以帮助你限制用户在一定时间内的请求次数。下面是如何使用 nestjs-rate-limiter 插件的基本步骤。

安装

首先,你需要安装 nestjs-rate-limiter 和必要的依赖:

npm install @nestjs-modules/rate-limiter redis

这里我们使用 Redis 作为存储后端。

配置

接下来,配置 RateLimiterModule 并将其导入到你的应用程序中。

import { Module } from '@nestjs/common';
import { RateLimiterModule } from '@nestjs-modules/rate-limiter';
import * as Redis from 'ioredis';

@Module({
  imports: [
    RateLimiterModule.forRoot({
      storeClient: new Redis({ host: 'localhost', port: 6379 }),
      points: 10, // 每个 IP 地址每秒允许的请求数
      duration: 1, // 时间窗口(秒)
    }),
  ],
})
export class AppModule {}

应用限流

然后,在你的控制器或特定路由上应用限流装饰器。

全局限流

如果你希望在整个应用中启用限流,可以在全局级别设置。

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { RateLimiterModule } from '@nestjs-modules/rate-limiter';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  
  app.useGlobalFilters(new RateLimiterModule.RateLimitFilter());

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

局部限流

你也可以在特定的控制器或路由上应用限流。

import { Controller, Get, Post, Req, Res } from '@nestjs/common';
import { Request, Response } from 'express';
import { RateLimiter } from '@nestjs-modules/rate-limiter';

@Controller('api')
@RateLimiter({
  points: 5,
  duration: 1,
})
export class ApiController {
  @Get()
  async get(@Req() req: Request, @Res() res: Response) {
    return res.send('Hello World!');
  }
}

自定义限流策略

你还可以自定义限流策略,比如基于用户ID或其他标识符进行限流。

@Get()
@RateLimiter({
  points: 5,
  duration: 1,
  keyGenerator: (req: Request) => req.headers['x-user-id'], // 使用用户ID作为键
})

异常处理

当请求超出限制时,你可以通过全局异常过滤器来处理这些异常。

import { ExceptionFilter, Catch, ArgumentsHost } from '@nestjs/common';
import { RateLimiterModule } from '@nestjs-modules/rate-limiter';

@Catch(RateLimiterModule.RateLimitException)
export class RateLimitExceptionFilter implements ExceptionFilter {
  catch(exception: RateLimiterModule.RateLimitException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    response.status(429).json({
      statusCode: 429,
      message: 'Too Many Requests',
    });
  }
}

将这个过滤器添加到你的模块中:

import { Module } from '@nestjs/common';
import { RateLimiterModule } from '@nestjs-modules/rate-limiter';
import { RateLimitExceptionFilter } from './rate-limit-exception.filter';

@Module({
  providers: [RateLimitExceptionFilter],
})
export class AppModule {}

以上就是如何在 NestJS 中使用 nestjs-rate-limiter 插件的基本步骤。希望这对你有所帮助!


3 回复

当然,了解nestjs-rate-limiter插件能给你的应用增加一层防护,防止被恶意请求淹没。想象一下,如果你的应用是个派对,那么这个插件就是门卫,确保每个人进来的速度不要太快。

首先,你需要安装@ nestjsx / rate-limit插件:

npm install @ nestjsx / rate-limit

然后,在你的模块中配置它:

import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
import { RateLimitGuard } from '@ nestjsx / rate-limit';

@Module({
  providers: [
    {
      provide: APP_GUARD,
      useClass: RateLimitGuard,
    },
  ],
})
export class AppModule {}

接下来,你可以根据需要配置速率限制规则。比如,限制每个IP每分钟只能发送100个请求:

import { RateLimitRule } from '@ nestjsx / rate-limit';

@Module({
  //...
  providers: [
    {
      provide: APP_GUARD,
      useClass: RateLimitGuard,
    },
  ],
  //...
})
export class AppModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(
        RateLimitRule({
          max: 100, // 最大请求数
          expire: 60 * 1000, // 过期时间(毫秒)
          header: 'x-app-rate-limit', // 自定义头部名称
        }),
      )
      .forRoutes('*'); // 应用于所有路由
  }
}

现在,你的应用就像一个有经验的门卫守护着夜店的大门,确保一切井然有序!


nestjs-rate-limiter 是一个基于 NestJS 的限流插件,它可以帮助你在 API 接口上实现访问频率限制。这在保护服务器免受恶意攻击或过载时非常有用。

安装

首先,你需要安装 nestjs-rate-limiter 及其依赖:

npm install @ nestjsx / rate-limiter-redis-store ioredis

这里我们使用了 Redis 作为存储后端,因为 Redis 提供了高效的键值存储,非常适合用于这种场景。

配置

接下来,你需要配置 Redis 并设置 RateLimiterRedis 实例。你可以通过在模块中提供自定义的 RateLimiterRedis 实例来完成这个操作。

import { Module } from '@nestjs/common';
import { RateLimiterRedis } from 'rate-limiter-flexible';
import { RedisModule } from 'nestjs-redis';

@Module({
  imports: [
    RedisModule.register({ url: 'redis://localhost:6379' }), // 配置 Redis 连接
  ],
  providers: [
    {
      provide: 'RATE_LIMITER',
      useFactory: async (redisClient) => {
        return new RateLimiterRedis({
          storeClient: redisClient,
          keyPrefix: 'ratelimit:',
          points: 10, // 每个 IP 允许的最大请求数量
          duration: 60, // 时间窗口(秒)
        });
      },
      inject: ['REDIS_CLIENT'],
    },
  ],
})
export class AppModule {}

使用

然后,你可以使用 @UseGuards 装饰器和创建自定义的守卫类来应用限流逻辑到你的控制器方法中。

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { RateLimiterRedis } from 'rate-limiter-flexible';
import { Inject } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { Request } from 'express';

@Injectable()
export class RateLimitGuard implements CanActivate {
  constructor(@Inject('RATE_LIMITER') private readonly rateLimiter: RateLimiterRedis) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest<Request>();
    const ip = request.ip;
    try {
      await this.rateLimiter.consume(ip);
      return true; // 请求通过限流
    } catch (err) {
      console.log(`请求被限流:${ip}`);
      return false; // 请求未通过限流
    }
  }
}

// 在控制器中应用
import { Controller, Get, UseGuards } from '@nestjs/common';
import { RateLimitGuard } from './guards/rate-limit.guard';

@Controller('example')
@UseGuards(RateLimitGuard)
export class ExampleController {
  @Get()
  getExample() {
    return { message: 'Hello World!' };
  }
}

以上就是如何在 NestJS 应用中使用 nestjs-rate-limiter 插件来实现限流功能的基本步骤。

nestjs-rate-limiter 是一个用于 NestJS 的限流插件。首先,你需要安装它:

npm install @nest-typed-ratelimit/rate-limiter

然后,在你的模块中导入 RateLimiterModule 并配置规则:

import { RateLimiterModule } from '@nest-typed-ratelimit/rate-limiter';

@Module({
  imports: [
    RateLimiterModule.forRoot({
      store: 'memory', // 存储方式,这里使用内存
      points: 10, // 允许的请求数量
      expire: 60, // 过期时间(秒)
    }),
  ],
})
export class AppModule {}

接着,在你的控制器或方法上添加装饰器来应用限流规则:

import { RateLimiter } from '@nest-typed-ratelimit/decorators';

@Controller('example')
export class ExampleController {
  @Get()
  @RateLimiter({ points: 2, expire: 60 })
  get() {
    return { message: 'Hello World' };
  }
}

这样就完成了基本配置。

回到顶部