Skip to main content

Rate Limit Menggunakan Redis di Aplikasi Express.js

· 4 min read
Jacky Rusly

Rate limit adalah batas akses suatu endpoint dalam waktu tertentu. Misalnya kita hanya memperbolehkan user untuk call endpoint /login 10 kali dalam 1 menit.

Rate limit ini berfungsi untuk menghindarkan server kita dari DDoS (Distributed Denial of Service) yang dapat membuat server kita down dan juga berfungsi untuk menghindarkan kita dari hacker mencari password user dengan melakukan brute force di endpoint login.

Untuk mengetahui lebih lanjut bagaimana cara menerapkannya, mari baca terus ya sampai selesai dan lebih baik lagi kalau sambil dipraktikkan.

Setup Project

Pertama-tama kita langsung saja membuat project Express.js. Buat 1 folder misalnya rate-limit-example dan buka folder tersebut di editor yang kalian pakai. Kalau saya pakai VSCode.

Kemudian buka terminal dan jalankan command berikut:

yarn init -y

Selanjutnya kita akan install dependencies yang dibutuhkan menggunakan command berikut:

yarn add express redis dotenv

Buat 1 file index.js yang berisi berikut ini:

const express = require('express');

const app = express();
const port = process.env.PORT || 3000;

app.get('/', (req, res) => {
res.json({
message: 'Hello World',
});
});

app.listen(port, () => {
console.log(`App listening on port ${port}`);
});

Jalankan aplikasi dengan command:

node index.js

Kemudian buka http://localhost:3000, maka hasilnya akan muncul:

{ "message": "Hello World" }

Setup Redis

Kalau di komputer kalian belum ada Redis, kalian bisa install sesuai dengan OS komputer kalian dengan mengikuti instruksi Redis Getting Started.

Di tutorial kali ini agar lebih mudah, saya akan menggunakan Redis Labs. Kalau kalian mau coba, bisa ke Redis Labs.

Redis Labs

Redis Labs ini di cloud dan ada free-tier-nya, sangat cocok dipakai untuk belajar karena tidak perlu menginstall Redis di komputer local kita.

Redis Client

Kita akan buat Redis Client di aplikasi kita. Buat satu file redis.js yang berisi berikut:

require('dotenv').config();

const redis = require('redis');

const redisClient = redis.createClient({
url: process.env.REDIS_URL,
});

module.exports = redisClient;

Kemudian kita akan buat 1 file .env untuk menampung credential Redis kita yang berisi:

REDIS_URL=(Url Redis kalian, kalau Redisnya di local komputer REDIS_URL ini bisa dibiarkan kosong)

Contoh kalau menggunakan Redis Labs:

REDIS_URL=redis://default:MNh4GnWxgQ60JeQMdqDZMBz1qtoWJqyf@redis-17145.c1.ap-southeast-1-1.ec2.cloud.redislabs.com:17145

Rate Limit Middleware

Buat satu file di middlewares/rate-limit.middleware.js yang berisi berikut:

const redisClient = require('../redis');

const rateLimitMiddleware = (limit, expireTime) => async (
req,
res,
next,
) => {
const ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress;
const key = `RATE_LIMIT_${ip}_${req.route.path}`;

const current = await redisClient.incr(key);

if (current > limit) {
return res.status(429).json({
message: 'Too Many Requests',
});
} else if (current === 1) {
await redisClient.expire(key, expireTime);
}

return next();
}

module.exports = rateLimitMiddleware;

Dapat dilihat isi file di atas. Key Redis yang dipakai adalah RATE_LIMIT_{IP}_{Route Path}. Kalian bisa sesuaikan dengan kebutuhan kalian.

Apply Rate Limit

Ada beberapa code yang harus diubah di file index.js:

const express = require('express');
const rateLimitMiddleware = require('./middlewares/rate-limit.middleware');
const redisClient = require('./redis');

const app = express();
const port = process.env.PORT || 3000;

const ONE_MINUTE = 60;

(async () => {
await redisClient.connect();

app.get('/', rateLimitMiddleware(10, ONE_MINUTE), (req, res) => {
res.json({
message: 'Hello World',
});
});

app.listen(port, () => {
console.log(`App listening on port ${port}`);
});
})();

Demo

Selanjutnya kita harus restart aplikasi kita:

node index.js

Kemudian coba buka http://localhost:3000 dan refresh sebanyak 11 kali.

Demo

Maka akan terkena 429 - Too Many Request dan setelah kita tunggu 1 menit maka endpoint tersebut akan ke 200 - OK kembali.

Penutup

Untuk contoh codenya bisa dilihat pada GitHub Repository Rate Limit Example.

Begitulah cara untuk melakukan rate limit menggunakan Redis di aplikasi Express.js kita. Semoga artikel ini bisa bermanfaat bagi teman-teman.