Gathering detailed insights and metrics for koa2-ratelimit-ioredis
Gathering detailed insights and metrics for koa2-ratelimit-ioredis
Gathering detailed insights and metrics for koa2-ratelimit-ioredis
Gathering detailed insights and metrics for koa2-ratelimit-ioredis
Rate-limiting middleware for Koa2 ES6. Use to limit repeated requests to APIs and/or endpoints such as password reset.
npm install koa2-ratelimit-ioredis
Typescript
Module System
Min. Node Version
Node Version
NPM Version
56.1
Supply Chain
94.2
Quality
71.5
Maintenance
25
Vulnerability
98.2
License
JavaScript (100%)
Total Downloads
18,553
Last Day
5
Last Week
107
Last Month
755
Last Year
8,386
58 Commits
5 Branches
1 Contributors
Updated on Jan 04, 2021
Minified
Minified + Gzipped
Latest Version
0.0.6
Package Id
koa2-ratelimit-ioredis@0.0.6
Unpacked Size
40.25 kB
Size
10.04 kB
File Count
14
NPM Version
7.1.0
Node Version
15.3.0
Cumulative downloads
Total Downloads
Last Day
-16.7%
5
Compared to previous day
Last Week
-63.1%
107
Compared to previous week
Last Month
178.6%
755
Compared to previous month
Last Year
118.2%
8,386
Compared to previous year
Rate-limiting middleware for Koa2 with async
await
. Use to limit repeated requests to APIs and/or endpoints such as password reset.
Note: This module is based on express-rate-limit and adapted to koa2 ES6 with the async
await
capabilities.
1$ npm install --save koa2-ratelimit-ioredis
For an API-only server where the rate-limiter should be applied to all requests:
1const RateLimit = require('koa2-ratelimit-ioredis').RateLimit; 2 3const limiter = RateLimit.middleware({ 4 interval: { min: 15 }, // 15 minutes = 15*60*1000 5 max: 100, // limit each IP to 100 requests per interval 6}); 7 8// apply to all requests 9app.use(limiter);
Create multiple instances to apply different rules to different routes:
1const RateLimit = require('koa2-ratelimit-ioredis').RateLimit; 2const KoaRouter = require('koa-router'); 3const router = new KoaRouter(); 4 5const getUserLimiter = RateLimit.middleware({ 6 interval: 15*60*1000, // 15 minutes 7 max: 100, 8 prefixKey: 'get/user/:id' // to allow the bdd to Differentiate the endpoint 9}); 10// add route with getUserLimiter middleware 11router.get('/user/:id', getUserLimiter, (ctx) => { 12 // Do your job 13}); 14 15const createAccountLimiter = RateLimit.middleware({ 16 interval: { hour: 1, min: 30 }, // 1h30 window 17 delayAfter: 1, // begin slowing down responses after the first request 18 timeWait: 3*1000, // slow down subsequent responses by 3 seconds per request 19 max: 5, // start blocking after 5 requests 20 prefixKey: 'post/user', // to allow the bdd to Differentiate the endpoint 21 message: "Too many accounts created from this IP, please try again after an hour" 22}); 23// add route with createAccountLimiter middleware 24router.post('/user', createAccountLimiter, (ctx) => { 25 // Do your job 26}); 27 28// mount routes 29app.use(router.middleware()) 30
Set default options to all your middleware:
1const RateLimit = require('koa2-ratelimit-ioredis').RateLimit;
2
3RateLimit.defaultOptions({
4 message: 'Get out.',
5 // ...
6});
7
8const getUserLimiter = RateLimit.middleware({
9 max: 100,
10 // message: 'Get out.', will be added
11});
12
13const createAccountLimiter = RateLimit.middleware({
14 max: 5, // start blocking after 5 requests
15 // message: 'Get out.', will be added
16});
ioredis options can be passed as config
config.type
can be cluster
/ sentinel
/ standalone
1const RateLimit = require('koa2-ratelimit-ioredis').RateLimit; 2const Stores = require('koa2-ratelimit').Stores; 3 4RateLimit.defaultOptions({ 5 message: 'Get out.', 6 store: new Stores.Redis({ 7 host: 'redis_host', 8 port: 'redis_port', 9 password: 'redis_password', 10 db: 1, 11 type: 'standalone' 12 }) 13}); 14 15const getUserLimiter = RateLimit.middleware({ 16 prefixKey: 'get/user/:id', 17}); 18router.get('/user/:id', getUserLimiter, (ctx) => {}); 19 20const createAccountLimiter = RateLimit.middleware.middleware({ 21 prefixKey: 'post/user', 22}); 23router.post('/user', createAccountLimiter, (ctx) => {}); 24 25// mount routes 26app.use(router.middleware())
1const Sequelize = require('sequelize');
2const RateLimit = require('koa2-ratelimit-ioredis').RateLimit;
3const Stores = require('koa2-ratelimit-ioredis').Stores;
4
5const sequelize = new Sequelize(/*your config to connected to bdd*/);
6
7RateLimit.defaultOptions({
8 message: 'Get out.',
9 store: new Stores.Sequelize(sequelize, {
10 tableName: 'ratelimits', // table to manage the middleware
11 tableAbuseName: 'ratelimitsabuses', // table to store the history of abuses in.
12 })
13});
14
15const getUserLimiter = RateLimit.middleware({
16 prefixKey: 'get/user/:id',
17});
18router.get('/user/:id', getUserLimiter, (ctx) => {});
19
20const createAccountLimiter = RateLimit.middleware.middleware({
21 prefixKey: 'post/user',
22});
23router.post('/user', createAccountLimiter, (ctx) => {});
24
25// mount routes
26app.use(router.middleware())
1const mongoose = require('mongoose');
2const RateLimit = require('koa2-ratelimit-ioredis').RateLimit;
3const Stores = require('koa2-ratelimit-ioredis').Stores;
4
5await mongoose.connect(/*your config to connected to bdd*/);
6
7RateLimit.defaultOptions({
8 message: 'Get out.',
9 store: new Stores.Mongodb(mongoose.connection, {
10 collectionName: 'ratelimits', // table to manage the middleware
11 collectionAbuseName: 'ratelimitsabuses', // table to store the history of abuses in.
12 }),
13});
14
A ctx.state.rateLimit
property is added to all requests with the limit
, current
, and remaining
number of requests for usage in your application code.
interval: Time Type - how long should records of requests be kept in memory. Defaults to 60000
(1 minute).
delayAfter: max number of connections during interval
before starting to delay responses. Defaults to 1
. Set to 0
to disable delaying.
timeWait: Time Type - how long to delay the response, multiplied by (number of recent hits - delayAfter
). Defaults to 1000
(1 second). Set to 0
to disable delaying.
max: max number of connections during interval
milliseconds before sending a 429
response code. Defaults to 5
. Set to 0
to disable.
message: Error message returned when max
is exceeded. Defaults to 'Too many requests, please try again later.'
statusCode: HTTP status code returned when max
is exceeded. Defaults to 429
.
headers: Enable headers for request limit (X-RateLimit-Limit
) and current usage (X-RateLimit-Remaining
) on all responses and time to wait before retrying (Retry-After
) when max
is exceeded.
skipFailedRequests: when true
, failed requests (response status >= 400) won't be counted. Defaults to false
.
whitelist: Array of whitelisted IPs to not be rate limited.
getUserId: Function used to get userId (if connected) to be added as key and saved in bdd, should an abuse case surface. Defaults:
1async function (ctx) { 2 const whereFinds = [ctx.state.user, ctx.user, ctx.state.User, 3 ctx.User, ctx.state, ctx]; 4 const toFinds = ['id', 'userId', 'user_id', 'idUser', 'id_user']; 5 for (const whereFind of whereFinds) { 6 if (whereFind) { 7 for (const toFind of toFinds) { 8 if (whereFind[toFind]) { 9 return whereFind[toFind]; 10 } 11 } 12 } 13 } 14 return null; 15},
keyGenerator: Function used to generate keys. By default userID (if connected) or the user's IP address. Defaults:
1async function (ctx) { 2 const userId = await this.options.getUserId(ctx); 3 if (userId) { 4 return `${this.options.prefixKey}|${userId}`; 5 } 6 return `${this.options.prefixKey}|${ctx.request.ip}`; 7}
skip: Function used to skip requests. Returning true from the function will skip limiting for that request. Defaults:
1async function (/*ctx*/) { 2 return false; 3}
handler: The function to execute once the max limit has been exceeded. It receives the request and the response objects. The "next" param is available if you need to pass to the next middleware. Defaults:
1async function (ctx/*, next*/) { 2 ctx.status = this.options.statusCode; 3 ctx.body = { message: this.options.message }; 4 if (this.options.headers) { 5 ctx.set('Retry-After', Math.ceil(this.options.interval / 1000)); 6 } 7}
onLimitReached: Function to listen each time the limit is reached. It call the store to save abuse, You can use it to debug/log. Defaults:
1async function (ctx) {
2 this.store.saveAbuse({
3 key: await this.options.keyGenerator(ctx),
4 ip: ctx.request.ip,
5 user_id: await this.options.getUserId(ctx),
6 });
7}
weight: Function to set the incrementation of the counter depending on the request. Defaults:
1async function (/*ctx*/) { 2 return 1; 3}
store: The storage to use when persisting rate limit attempts. By default, the MemoryStore is used.
Avaliable data stores are:
The delayAfter
and timeWait
options were written for human-facing pages such as login and password reset forms.
For public APIs, setting these to 0
(disabled) and relying on only interval
and max
for rate-limiting usually makes the most sense.
Time type can be milliseconds or an object
1 Times = { 2 ms ?: number, 3 sec ?: number, 4 min ?: number, 5 hour ?: number, 6 day ?: number, 7 week ?: number, 8 month ?: number, 9 year ?: number, 10 };
Examples
1 RateLimit.middleware({ 2 interval: { hour: 1, min: 30 }, // 1h30 window 3 timeWait: { week: 2 }, // 2 weeks window 4 }); 5 RateLimit.middleware({ 6 interval: { ms: 2000 }, // 2000 ms = 2 sec 7 timeWait: 2000, // 2000 ms = 2 sec 8 });
MIT © Rajan Panigrahi
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
Found 0/30 approved changesets -- score normalized to 0
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no SAST tool detected
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
license file not detected
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
52 existing vulnerabilities detected
Details
Score
Last Scanned on 2025-06-23
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More