Rate limiting bảo vệ API khỏi spam, brute-force và DDoS.
Fixed window đếm request trong khung cố định (0:00-0:15) — dễ lách bằng cách dồn burst vào cuối khung cũ rồi đầu khung mới. Sliding window trượt theo thời gian thực nên chính xác hơn, đổi lại cần Redis.
express-rate-limit dùng fixed window:
js
rateLimit({
windowMs: 15 * 60 * 1000,
max: 100,
standardHeaders: true, // trả RateLimit-Limit / Remaining / Reset
legacyHeaders: false,
keyGenerator: (req) => req.user?.id || req.ip, // user đăng nhập tính theo userId
})- Distributed: dùng store
rate-limit-redisđể nhiều instance chia sẻ counter — bắt buộc khi chạy cluster hoặc nhiều server. Để in-memory thì mỗi instance đếm riêng, hạn mức thật thànhmax * số instance. - Hạn mức theo endpoint: auth 5 req/15 phút, API thường 100 req/15 phút, endpoint public 1000 req/15 phút.
Lưu ý: đứng sau reverse proxy thì req.ip là IP của proxy — phải app.set('trust proxy', 1) để lấy IP thật từ X-Forwarded-For, không thì cả thế giới chung một counter.