@nathapp/nestjs-throttler
v3.0.0
Published
NestJS Throttler with trusted proxy-aware IP resolution
Readme
@nathapp/nestjs-throttler
Proxy-aware rate limiting wrapper for NestJS applications using @nestjs/throttler.
Features
- Proxy-aware IP detection — Accurate client IP resolution behind reverse proxies and load balancers
- Trust proxy configuration — Support for X-Forwarded-For header validation with CIDR matching
- Express & Fastify support — Works with both NestJS adapters
- Drop-in replacement — Compatible with @nestjs/throttler decorators and features
- IPv6 support — Full IPv6 address and CIDR range matching
- Trusted proxy presets — Pre-configured for Cloudflare, AWS, Google Cloud, and more
Installation
npm install @nathapp/nestjs-throttler @nestjs/throttlerQuick Start
import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
import { ThrottlerModule, DefaultThrottlerGuard } from '@nathapp/nestjs-throttler';
@Module({
imports: [
ThrottlerModule.forRoot({
throttlers: [
{ name: 'short', ttl: 1000, limit: 3 },
{ name: 'long', ttl: 60000, limit: 100 }
],
trustProxy: {
enabled: true,
trustedProxies: ['10.0.0.0/8', 'cloudflare']
}
})
],
providers: [
{
provide: APP_GUARD,
useClass: DefaultThrottlerGuard,
}
]
})
export class AppModule {}Trust Proxy Configuration
Basic Setup
ThrottlerModule.forRoot({
throttlers: [{ name: 'default', ttl: 60000, limit: 10 }],
trustProxy: {
enabled: true,
trustedProxies: ['127.0.0.0/8', '10.0.0.0/8']
}
})Using Preset Providers
import { TRUSTED_PROXY_PRESETS } from '@nathapp/nestjs-common';
ThrottlerModule.forRoot({
throttlers: [{ name: 'default', ttl: 60000, limit: 10 }],
trustProxy: {
enabled: true,
trustedProxies: ['cloudflare', 'aws', 'gcp']
}
})Available presets: cloudflare, aws, gcp, azure, digitalocean, fastly, cloudfront, heroku
Async Configuration
ThrottlerModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
throttlers: [{ name: 'default', ttl: 60000, limit: 10 }],
trustProxy: {
enabled: config.get('TRUST_PROXY'),
trustedProxies: config.get('TRUSTED_PROXIES')
}
})
})Express vs Fastify Support
The module automatically detects and supports both Express and Fastify adapters.
// Express
const app = await NestFactory.create(AppModule);
// Fastify
const app = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter()
);Custom Rate Limiting
Using @Throttle() Decorator
import { Controller, Get } from '@nestjs/common';
import { Throttle } from '@nestjs/throttler';
@Controller()
export class UserController {
// Override default limit for this endpoint
@Throttle({ default: { limit: 5, ttl: 60000 } })
@Get('users')
getUsers() {
return [];
}
}Using @SkipThrottle() Decorator
import { Controller, Get } from '@nestjs/common';
import { SkipThrottle } from '@nestjs/throttler';
@Controller()
export class HealthController {
// Skip throttling for health checks
@SkipThrottle()
@Get('health')
check() {
return { status: 'ok' };
}
}Provider Capabilities
This wrapper adds the following capabilities over raw @nestjs/throttler:
| Feature | @nestjs/throttler | @nathapp/nestjs-throttler | |---------|-------------------|---------------------------| | Basic rate limiting | ✅ | ✅ | | Multiple throttlers | ✅ | ✅ | | Custom storage | ✅ | ✅ | | Trust proxy support | ❌ | ✅ | | X-Forwarded-For validation | ❌ | ✅ | | CIDR matching | ❌ | ✅ | | IPv6 support | ❌ | ✅ | | Preset proxy providers | ❌ | ✅ |
How It Works
The DefaultThrottlerGuard extends @nestjs/throttler's ThrottlerGuard and overrides the getTracker() method to use getClientIp() from @nathapp/nestjs-common. This function:
- Checks if trust proxy is enabled
- Validates request origin against trusted proxy list (with CIDR support)
- Parses X-Forwarded-For header (right-to-left, skipping trusted proxies)
- Falls back to socket.remoteAddress if headers are untrusted
- Returns the real client IP for rate limiting
Security Considerations
- Always configure trusted proxies — Without trust proxy configuration, X-Forwarded-For headers are ignored and socket.remoteAddress is used
- Use CIDR ranges — Prefer CIDR notation (e.g.,
10.0.0.0/8) over individual IPs for internal networks - Preset providers are vetted — Cloud provider presets (cloudflare, aws, etc.) are maintained and updated with official IP ranges
- IPv6 support — Both IPv4 and IPv6 addresses/CIDRs are fully supported
License
ISC
Author
William Khoo
