aldikhan13

Express Custom Rate Limiter Middleware Using Redis

Apr 19th, 2021 (edited)
1,578
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { Request, Response, NextFunction } from 'express'
  2. import IORedis from 'ioredis'
  3. import ip from 'request-ip'
  4.  
  5. export async function rateLimiterById(req: Request, res: Response, next: NextFunction): Promise<any> {
  6.     // setup redis
  7.     const io = new IORedis({
  8.         host: process.env.REDIS_HOST || 'localhost',
  9.         port: parseInt(process.env.REDIS_PORT || ''),
  10.         db: 1
  11.     })
  12.     // store id to redis
  13.     await io.set(`redis-id:${req.user.id}`, req.user.uid)
  14.     // get request by id
  15.     const getId = await io.get(`redis-id:${req.user.uid}`)
  16.     // counter count request
  17.     const maxCounterRequest = await io.incrby(`counter-id:${req.user.id}`, 1)
  18.  
  19.     if (getId === req.user.id && maxCounterRequest <= 50) {
  20.         await io.expire(`counter-id:${req.user.id}`, 10)
  21.     } else {
  22.         await io.del(`redis-id:${req.user.id}`)
  23.         return res.status(429).json({
  24.             status: 'ERROR TO MANY REQUEST',
  25.             code: 'AX2AC5R',
  26.             message: 'cannot access this endpoint, after 10 second is over'
  27.         })
  28.     }
  29.  
  30.     next()
  31. }
  32.  
  33. export async function rateLimiterByIp(req: Request, res: Response, next: NextFunction): Promise<any> {
  34.     // setup redis
  35.     const io = new IORedis({
  36.         host: process.env.REDIS_HOST || 'localhost',
  37.         port: parseInt(process.env.REDIS_PORT || ''),
  38.         db: 2
  39.     })
  40.     const getIp = ip.getClientIp(req)
  41.     // store id to redis
  42.     await io.set(`redis-ip:${getIp}`, `${getIp}`)
  43.     // get request by id
  44.     const getStoreIp = await io.get(`redis-ip:${getIp}`)
  45.     // counter count request
  46.     const maxCounterRequest = await io.incrby(`counter-ip:${getIp}`, 1)
  47.  
  48.     if (getStoreIp === getIp && maxCounterRequest <= 50) {
  49.         await io.expire(`counter-ip:${getIp}`, 10)
  50.     } else {
  51.         await io.del(`redis-ip:${getIp}`)
  52.         return res.status(429).json({
  53.             status: 'ERROR TO MANY REQUEST',
  54.             code: 'AX2AC5R',
  55.             message: 'cannot access this endpoint, after 10 second is over'
  56.         })
  57.     }
  58.  
  59.     next()
  60. }
Add Comment
Please, Sign In to add comment