fix(#19): Implement rate limiting for auth and write-heavy endpoints
Some checks are pending
Docker Test / test (push) Waiting to run
Some checks are pending
Docker Test / test (push) Waiting to run
This commit is contained in:
parent
a0fc6fe236
commit
2b09cf05eb
3 changed files with 128 additions and 7 deletions
52
backend/src/middleware/rateLimit.js
Normal file
52
backend/src/middleware/rateLimit.js
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
// Einfache Rate-Limiting-Middleware ohne externe Abhängigkeiten
|
||||
|
||||
// Konfigurierbare Limits über Umgebungsvariablen
|
||||
const DEFAULT_WINDOW_MS = parseInt(process.env.RATE_LIMIT_WINDOW_MS) || 15 * 60 * 1000; // 15 Minuten
|
||||
const DEFAULT_MAX_REQUESTS = parseInt(process.env.RATE_LIMIT_MAX_REQUESTS) || 100;
|
||||
const DEFAULT_AUTH_WINDOW_MS = parseInt(process.env.RATE_LIMIT_AUTH_WINDOW_MS) || 5 * 60 * 1000; // 5 Minuten
|
||||
const DEFAULT_AUTH_MAX_REQUESTS = parseInt(process.env.RATE_LIMIT_AUTH_MAX_REQUESTS) || 5;
|
||||
|
||||
// Speicher für IP-Adressen und Request-Zähler
|
||||
const rateLimits = new Map();
|
||||
|
||||
const rateLimit = (options = {}) => {
|
||||
const windowMs = options.windowMs || DEFAULT_WINDOW_MS;
|
||||
const maxRequests = options.max || DEFAULT_MAX_REQUESTS;
|
||||
|
||||
return (req, res, next) => {
|
||||
const key = req.ip; // IP-Adresse als Schlüssel
|
||||
const now = Date.now();
|
||||
|
||||
if (!rateLimits.has(key)) {
|
||||
rateLimits.set(key, { count: 1, windowStart: now });
|
||||
} else {
|
||||
const data = rateLimits.get(key);
|
||||
if (now - data.windowStart > windowMs) {
|
||||
// Fenster abgelaufen, neues Fenster starten
|
||||
rateLimits.set(key, { count: 1, windowStart: now });
|
||||
} else {
|
||||
// Prüfen, ob Limit erreicht wurde
|
||||
if (data.count >= maxRequests) {
|
||||
return res.status(429).json({
|
||||
error: 'Too many requests',
|
||||
retryAfter: Math.ceil((windowMs - (now - data.windowStart)) / 1000)
|
||||
});
|
||||
}
|
||||
// Zähler erhöhen
|
||||
rateLimits.set(key, { count: data.count + 1, windowStart: data.windowStart });
|
||||
}
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
};
|
||||
|
||||
// Spezielle Middleware für Auth-Endpunkte mit kürzerem Fenster und niedrigerem Limit
|
||||
const authRateLimit = (options = {}) => {
|
||||
const windowMs = options.windowMs || DEFAULT_AUTH_WINDOW_MS;
|
||||
const maxRequests = options.max || DEFAULT_AUTH_MAX_REQUESTS;
|
||||
|
||||
return rateLimit({ windowMs, max: maxRequests });
|
||||
};
|
||||
|
||||
module.exports = { rateLimit, authRateLimit };
|
||||
Loading…
Add table
Add a link
Reference in a new issue