Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fastify-rate-limit

Package Overview
Dependencies
Maintainers
9
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fastify-rate-limit

A low overhead rate limiter for your routes

  • 2.2.0
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
3.7K
decreased by-28.3%
Maintainers
9
Weekly downloads
 
Created
Source

fastify-rate-limit

Greenkeeper badge js-standard-style Build Status

A low overhead rate limiter for your routes. Supports Fastify 2.x versions.

Please refer to this branch and related versions for Fastify 1.x compatibility.

Install

npm i fastify-rate-limit

Usage

Register the plugin pass to it some custom option.
This plugin will add an onRequest hook to check if the clients (based on their ip) has done too many request in the given timeWindow.

const fastify = require('fastify')()

fastify.register(require('fastify-rate-limit'), {
  max: 100,
  timeWindow: '1 minute'
})

fastify.get('/', (req, reply) => {
  reply.send({ hello: 'world' })
})

fastify.listen(3000, err => {
  if (err) throw err
  console.log('Server listening at http://localhost:3000')
})

In case a client reaches the maximum number of allowed requests, a standard Fastify error will be returned to the user with the status code setted to 429:

{
  statusCode: 429,
  error: 'Too Many Requests',
  message: 'Rate limit exceeded, retry in 1 minute'
}

Options

You can pass the following options during the plugin registration:

fastify.register(require('fastify-rate-limit'), {
  global : false, // default true
  max: 3, // default 1000
  timeWindow: 5000, // default 1000 * 60
  cache: 10000, // default 5000
  whitelist: ['127.0.0.1'], // default []
  redis: new Redis({ host: '127.0.0.1' }), // default null
  skipOnError: true, // default false
  keyGenerator: function(req) { /* ... */ }, // default (req) => req.raw.ip
})
  • global : indicates if the plugin should apply the rate limit setting to all routes within the encapsulation scope
  • max: is the maximum number of requests a single client can perform inside a timeWindow.
  • timeWindow: the duration of the time window. It can be expressed in milliseconds or as a string (in the ms format)
  • cache: this plugin internally uses a lru cache to handle the clients, you can change the size of the cache with this option
  • whitelist: array of string of ips to exclude from rate limiting
  • redis: by default this plugins uses an in-memory store, which is fast but if you application works on more than one server it is useless, since the data is store locally.
    You can pass a Redis client here and magically the issue is solved. To achieve the maximum speed, this plugins requires the use of ioredis
  • skipOnError: if true it will skip errors generated by the storage (eg, redis not reachable).
  • keyGenerator: a function to generate a unique identifier for each incoming request. Defaults to (req) => req.ip, the IP is resolved by fastify using req.connection.remoteAddress or req.headers['x-forwarded-for'] if trustProxy option is enabled. Use it if you want to override this behavior

keyGenerator example usage:

fastify.register(require('fastify-rate-limit'), {
  /* ... */
  keyGenerator: function(req) {
    return req.headers['x-real-ip'] // nginx
    || req.headers['x-client-ip'] // apache
    || req.headers['x-forwarded-for'] // use this only if you trust the header
    || req.session.username // you can limit based on any session value
    || req.raw.ip // fallback to default
})

Options on the endpoint itself

Rate limiting can be configured also for some routes, applying the configuration independently.

For example the whitelist if configured:

  • on the plugin registration will affect all endpoints within the encapsulation scope
  • on the route declaration will affect only the targeted endpoint

The global whitelist is configured when registering it with fastify.register(...).

The endpoint whitelist is set on the endpoint directly with the { config : { rateLimit : { whitelist : [] } } } object.

ACL checking is performed based on the value of the key from the keyGenerator.

In this example we are checking the IP address, but it could be a whitelist of specific user identifiers (like JWT or tokens):

const fastify = require('fastify')()

fastify.register(require('fastify-rate-limit'),
  {
    global : false, // don't apply these settings to all the routes of the context
    max: 3000, // default global max rate limit
    whitelist: ['192.168.0.10'], // global whitelist access. 
    redis: redis, // custom connection to redis
  })

// add a limited route with this configuration plus the global one
fastify.get('/', {
  config: {
    rateLimit: {
      max: 3,
      timeWindow: '1 minute'
    }
  }
}, (req, reply) => {
  reply.send({ hello: 'from ... root' })
})

// add a limited route with this configuration plus the global one
fastify.get('/private', {
  config: {
    rateLimit: {
      max: 3,
      timeWindow: '1 minute'
    }
  }
}, (req, reply) => {
  reply.send({ hello: 'from ... private' })
})

// this route doesn't have any rate limit
fastify.get('/public', (req, reply) => {
  reply.send({ hello: 'from ... public' })
})

// add a limited route with this configuration plus the global one
fastify.get('/public/sub-rated-1', {
  config: {
    rateLimit: {
      timeWindow: '1 minute',
      whitelist: ['127.0.0.1'],
      onExceeding: function (req) {
        console.log('callback on exceededing ... executed before response to client')
      },
      onExceeded: function (req) {
        console.log('callback on exceeded ... to black ip in security group for example, req is give as argument')
      }
    }
  }
}, (req, reply) => {
  reply.send({ hello: 'from sub-rated-1 ... using default max value ... ' })
})

In the route creation you can override the same settings of the plugin registration plus the additionals options:

  • onExceeding : callback that will be executed each time a request is made to a route that is rate limited
  • onExceeded : callback that will be executed when a user reached the maximum number of tries. Can be useful to blacklist clients

License

MIT

Copyright © 2018 Tomas Della Vedova

Keywords

FAQs

Package last updated on 30 Jun 2019

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc