koajs / ratelimit

Rate limiter middleware
MIT License
485 stars 57 forks source link

Can the max and duration parameters be dynamically adjusted according to the user info or IP? #41

Closed small-tou closed 6 years ago

small-tou commented 6 years ago

by setting up Max and duration as async function, are there any big pits?

dead-horse commented 6 years ago

I don't think it's a good idea, maybe you should use https://github.com/tj/node-ratelimiter independently

small-tou commented 6 years ago

why?i think most business scenarios need this feature.

dead-horse commented 6 years ago

it's easy to do this, you should separate by each situation with different key(or prefix)

dead-horse commented 6 years ago

try opts.id(ctx) to generate you own id may work.

small-tou commented 6 years ago

要不要用中文交流,我的意思是 给不同的用户 不同的请求频率限制,可以自己根据用户的 ip 或者 ctx 上挂载的信息来决定他的 max 和 duration 参数的值的大小。(/ω\)

dead-horse commented 6 years ago

上面给你答案了,用 opts.id(ctx) 来根据不同用户场景生成 id。否则会冲突

small-tou commented 6 years ago

opts.id(ctx) 只是可以定制区分用户场景的规则,但是无法给每个用户场景再定义他拥有的频率规则。 例如:我有一个 vip 会员和 普通用户的区别,他们每分钟可以访问的频次是不同的,甚至 vip 用户的规则是按照小时来的,普通用户是按照分钟来的。

app.use(ratelimit({
  db: new Redis(),
  duration: 60000,
  // duration: async (ctx) => { return 1000; } // can define by user's info
  errorMessage: 'Sometimes You Just Have to Slow Down.',
  id: (ctx) => ctx.ip,
  headers: {
    remaining: 'Rate-Limit-Remaining',
    reset: 'Rate-Limit-Reset',
    total: 'Rate-Limit-Total'
  },
  max: 100,
  // max: async (ctx) => { return 100; } // can define by user's info
  disableHeader: false,
}));
dead-horse commented 6 years ago

所以我说复杂场景建议自己实现,不要基于这个中间件来搞了,本来就没几行代码,抄一遍好了

small-tou commented 6 years ago

好的,大佬。自己加了两句代码:https://github.com/xinyu198736/ratelimit

rocktimsaikia commented 2 years ago

Did anyone find any simple solution to this issue yet? I need to increase the max value based on user's API key. Something like express's rate limit middleware, where we can pass a function to the max option.

  // max could also be an async function or return a promise
  max: function(req, res) {
    if (isPremium(req)) {
      return 10;
    }
    return 5;
  }