koa-ratelimit使用注意了

71 阅读1分钟

如果你的后台使用koa,并使用了koa-ratelimit
那么如果客户端使用多级代理网络,那么你将喜提BUG一枚!

AssertionError [ERR_ASSERTION]: .id required
at new Limiter (\node_modules\koa-ratelimit\limiter\memory.js:36:5)
at ratelimit (\node_modules\koa-ratelimit\index.js:71:17)
at async serve (\node_modules\_koa-static@5.0.0@koa-static\index.js:53:9)

## 服务全给停了,哈哈哈刺激不?

以下是官方例子


const Koa = require('koa');
const ratelimit = require('koa-ratelimit');
const Redis = require('ioredis');
const app = new Koa();
 
// apply rate limit
app.use(ratelimit({
  driver: 'redis',
  db: new Redis(),
  duration: 60000,
  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,
  disableHeader: false,
  whitelist: (ctx) => {
    // some logic that returns a boolean
  },
  blacklist: (ctx) => {
    // some logic that returns a boolean
  }
}));
 
// response middleware
app.use(async (ctx) => {
  ctx.body = 'Stuff!';
});
 
// run server
app.listen(
  3000,
  () => console.log('listening on port 3000')
);

这里很明显有个id id: (ctx) => ctx.ip,

别犹豫改吧!

id: (ctx) => {
     if (ctx.ip) {
        return ctx.ip
      } else {
        let ip = ctx.request.ip?ctx.request.ip:"::ffff:127.0.0.1"
        if (ctx.request.headers["x-real-ip"]) {
          ip = ctx.request.headers["x-real-ip"]
        } else if (ctx.request.headers["x-forwarded-for"]) {
          ip = ctx.request.headers["x-forwarded-for"].split(",")[0].trim()
        } else if (!ip) {
          ip = "::ffff:127.0.0.1"
        }else{
          ip = "::ffff:127.0.0.1"
        }
        console.log("多级代理IP", ip)
        return ip
      }
    },