Node.js में Rate Limiting: API को ओवरलोड और हमलों से बचाएं
रेट लिमिटिंग (Rate limiting) यानी अनुरोधों की गति को सीमित करना, किसी भी Node.js वेब एप्लिकेशन के लिए एक महत्वपूर्ण तंत्र है। यह नियंत्रित करता है कि कोई क्लाइंट एक निश्चित समय में सर्वर पर कितने अनुरोध भेज सकता है। रेट लिमिटिंग के बिना, आपका API DDoS हमलों, आकस्मिक ओवरलोड और संसाधनों के अत्यधिक उपयोग के प्रति संवेदनशील हो जाता है।
रेट लिमिटिंग क्यों ज़रूरी है?
- ब्रूट फोर्स से सुरक्षा: सिस्टम में बार-बार लॉगिन करने के प्रयासों को रोकता है।
- DDoS रोकथाम: सर्विस डिनायल हमलों के प्रभाव को सीमित करता है।
- संसाधनों का उचित वितरण: सभी उपयोगकर्ताओं के लिए समान पहुंच सुनिश्चित करता है।
- लागत बचत: सर्वर और डेटाबेस पर लोड कम करता है।
- SLA अनुपालन: सेवा स्तर समझौतों को पूरा करने में मदद करता है।
रेट लिमिटिंग के मुख्य एल्गोरिदम
गति सीमा लागू करने के कई तरीके हैं। आइए सबसे लोकप्रिय तरीकों पर नज़र डालते हैं:
1. Sliding Window (स्लाइडिंग विंडो)
सबसे आम एल्गोरिदम। अनुरोधों को समय विंडो (जैसे, 1 मिनट) में समूहित किया जाता है। यदि अनुरोधों की संख्या सीमा से अधिक हो जाती है, तो नई विंडो शुरू होने तक अगले अनुरोधों को अस्वीकार कर दिया जाता है।
2. Token Bucket (टोकन बकेट)
एक वर्चुअल "बाल्टी" में टोकन होते हैं। प्रत्येक अनुरोध एक टोकन का उपभोग करता है। टोकन एक निश्चित दर पर भरे जाते हैं। यदि बाल्टी खाली है, तो अनुरोध अस्वीकार कर दिया जाता है।
3. Leaky Bucket (लीकी बकेट)
अनुरोध एक कतार में आते हैं और एक स्थिर गति से संसाधित होते हैं। यदि कतार भर जाती है, तो अनुरोधों को हटा दिया जाता है।
Node.js के लिए रेट लिमिटिंग लाइब्रेरीज़
1. express-rate-limit
Express.js के लिए सबसे लोकप्रिय लाइब्रेरी। उपयोग में आसान और अनुकूलन योग्य।
const rateLimit = require('express-rate-limit');
// अनुरोध सीमित करने के लिए मिडलवेयर बनाएं
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 मिनट
max: 100, // प्रति विंडो अधिकतम 100 अनुरोध
message: 'बहुत अधिक अनुरोध, कृपया बाद में प्रयास करें।',
standardHeaders: true, // RateLimit-* हेडर लौटाता है
legacyHeaders: false, // X-RateLimit-* हेडर बंद करता है
});
// सभी रूट्स पर लागू करें
app.use(limiter);
// या केवल विशिष्ट रूट पर लागू करें
app.use('/api/login', limiter);
2. bottleneck
एक सार्वभौमिक लाइब्रेरी जो किसी भी एसिंक्रोनस ऑपरेशन के साथ काम करती है। Token Bucket और Leaky Bucket एल्गोरिदम को सपोर्ट करती है।
const Bottleneck = require('bottleneck');
// लिमिटर बनाएं: प्रति सेकंड 5 अनुरोध
const limiter = new Bottleneck({
minTime: 200, // अनुरोधों के बीच 200 मि.से.
maxConcurrent: 5, // अधिकतम 5 समवर्ती अनुरोध
reservoir: 100, // टोकन की प्रारंभिक संख्या
reservoirRefreshAmount: 100,
reservoirRefreshInterval: 60 * 1000, // हर मिनट रिफ्रेश
});
// फंक्शन को लिमिटर में लपेटें
async function fetchData(url) {
const response = await fetch(url);
return response.json();
}
const limitedFetch = limiter.wrap(fetchData);
// उपयोग
const data = await limitedFetch('https://api.example.com/data');
3. rate-limiter-flexible
Redis, MongoDB, Memcached और अन्य स्टोरेज के साथ काम करने वाली लचीली लाइब्रेरी। वितरित सिस्टम के लिए आदर्श।
const { RateLimiterRedis } = require('rate-limiter-flexible');
const Redis = require('ioredis');
const redisClient = new Redis();
const rateLimiter = new RateLimiterRedis({
storeClient: redisClient,
keyPrefix: 'middleware',
points: 10, // 10 अनुरोध
duration: 1, // 1 सेकंड में
});
app.use(async (req, res, next) => {
try {
await rateLimiter.consume(req.ip);
next();
} catch (rejRes) {
res.status(429).send('बहुत अधिक अनुरोध');
}
});
व्यावहारिक उदाहरण
उदाहरण 1: API कुंजियों के लिए रेट लिमिटिंग
API कुंजियों के लिए रेट लिमिटिंग लागू करना बहुत ज़रूरी है। यह सुनिश्चित करता है कि कोई भी उपयोगकर्ता आपके संसाधनों का दुरुपयोग न करे।
const rateLimit = require('express-rate-limit');
const apiLimiter = rateLimit({
windowMs: 60 * 60 * 1000, // 1 घंटा
max: 1000, // प्रति घंटे अधिकतम 1000 अनुरोध
keyGenerator: (req) => req.headers['x-api-key'], // API कुंजी के आधार पर सीमा
message: 'API कुंजी की सीमा समाप्त। कृपया बाद में प्रयास करें।'
});
app.use('/api/', apiLimiter);
उदाहरण 2: लॉगिन एंडपॉइंट के लिए रेट लिमिटिंग
लॉगिन एंडपॉइंट पर रेट लिमिटिंग ब्रूट फोर्स हमलों को रोकने में मदद करता है।
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 मिनट
max: 5, // प्रति 15 मिनट में अधिकतम 5 प्रयास
message: 'बहुत अधिक लॉगिन प्रयास। कृपया 15 मिनट बाद पुनः प्रयास करें।'
});
app.post('/login', loginLimiter, (req, res) => {
// लॉगिन लॉजिक
});
बेस्ट प्रैक्टिसेज़
- हमेशा रेट लिमिटिंग लागू करें: चाहे आपका एप्लिकेशन छोटा हो या बड़ा, रेट लिमिटिंग ज़रूरी है।
- उपयुक्त सीमाएं चुनें: अपने एप्लिकेशन की क्षमता और उपयोगकर्ता की ज़रूरतों के अनुसार सीमाएं तय करें।
- हेडर का उपयोग करें: RateLimit-* हेडर क्लाइंट को उनकी वर्तमान सीमा के बारे में सूचित करते हैं।
- लॉगिंग और मॉनिटरिंग: रेट लिमिटिंग इवेंट्स को लॉग करें और नियमित रूप से मॉनिटर करें।
- वितरित सिस्टम के लिए Redis का उपयोग करें: यदि आपके पास कई सर्वर हैं, तो Redis जैसे सेंट्रलाइज़्ड स्टोरेज का उपयोग करें।
निष्कर्ष
रेट लिमिटिंग Node.js एप्लिकेशन की सुरक्षा और प्रदर्शन के लिए एक आवश्यक उपकरण है। सही लाइब्रेरी और एल्गोरिदम चुनकर, आप अपने API को ओवरलोड और दुर्भावनापूर्ण हमलों से बचा सकते हैं। express-rate-limit, bottleneck और rate-limiter-flexible जैसी लाइब्रेरीज़ के साथ, आप आसानी से अपने एप्लिकेशन में रेट लिमिटिंग लागू कर सकते हैं।