Stoppe den API-Missbrauch
Wenn du eine öffentliche API betreibst, ist es nur eine Frage der Zeit, bis Bots oder neugierige Skripte versuchen, deine Endpunkte hunderte Male pro Sekunde aufzurufen. Das Ergebnis? Deine Datenbank geht in die Knie, deine Serverkosten steigen und echte Nutzer schauen in die Röhre.
Die Lösung heißt Rate-Limiting. Wir begrenzen die Anzahl der erlaubten Anfragen pro IP-Adresse in einem festen Zeitfenster. In diesem Guide bauen wir einen extrem performanten Schutzschild mit Node.js und Redis.
Vorbereitung: Dein isolierter Sicherheits-Check
Bevor wir den Schutzschild hochfahren, erstellen wir eine saubere Testumgebung:
mkdir mein-api-schutz
cd mein-api-schutz
Schritt 1: Das Docker-Zentralgestirn
Wir brauchen eine Node.js App und einen Redis-Server, der sich die IP-Adressen und deren Request-Zähler merkt.
Erstelle die Datei: mein-api-schutz/docker-compose.yaml:
version: '3.8'
services:
app:
image: node:18-alpine
working_dir: /app
volumes:
- .:/app
ports:
- "3000:3000"
command: sh -c "npm install && node server.js"
depends_on:
- redis
redis:
image: redis:alpine
ports:
- "6379:6379"
Schritt 2: Die Node.js Dateien
Wir benötigen zwei Dateien: Einmal die package.json mit unseren Abhängigkeiten und die eigentliche server.js Logik.
mein-api-schutz/package.json:
{
"dependencies": {
"express": "^4.18.2",
"redis": "^4.6.10",
"express-rate-limit": "^7.1.1",
"rate-limit-redis": "^4.0.0"
}
}
mein-api-schutz/server.js:
const express = require('express');
const { RedisStore } = require('rate-limit-redis');
const { createClient } = require('redis');
const { rateLimit } = require('express-rate-limit');
const app = express();
const client = createClient({ url: 'redis://redis:6379' });
async function startServer() {
await client.connect();
// Der Schutzschild-Middleware
const limiter = rateLimit({
windowMs: 1 * 60 * 1000, // Zeitfenster: 1 Minute
limit: 5, // Maximal 5 Anfragen pro IP pro Fenster
standardHeaders: 'draft-7',
legacyHeaders: false,
store: new RedisStore({
sendCommand: (...args) => client.sendCommand(args),
}),
message: { error: '⚠️ Zu viele Anfragen! Versuchs in einer Minute wieder.' }
});
// Schutzschild auf alle Routen anwenden
app.use(limiter);
app.get('/', (req, res) => {
res.json({ message: '👋 Willkommen auf der sicheren API!' });
});
app.listen(3000, () => console.log('🛡️ API-Schutzschild läuft auf Port 3000'));
}
startServer();
Schritt 3: Den Schutzschild testen
Fahre dein System hoch:
docker compose up -d
Der Härtetest: Flute deine API!
Wir nutzen curl, um schnell nacheinander Anfragen zu senden. Da wir das Limit auf 5 gesetzt haben, sollte die 6. Anfrage geblockt werden.
Führe diesen Befehl 6 Mal hintereinander aus:
curl http://localhost:3000/
Bei den ersten 5 Versuchen erhältst du ein freundliches "Willkommen". Beim 6. Mal jedoch schlägt der Schutz zu:
{ "error": "⚠️ Zu viele Anfragen! Versuchs in einer Minute wieder." }
⚠️ 📸 SCREENSHOT ANFRAGE: Hier einen Screenshot vom Terminal einfügen, der die 5 erfolgreichen Antworten und die abschließende Fehlermeldung (429 Too Many Requests) zeigt.
Warum Redis nutzen?
Theoretisch kann express-rate-limit die Daten auch im Arbeitsspeicher der Node.js App halten. Das hat aber einen riesigen Nachteil: Wenn du deine App neu startest oder mehrere Instanzen (Cluster) nutzt, wird das Limit für jeden Nutzer zurückgesetzt. Mit Redis haben alle Instanzen ein gemeinsames Gedächtnis – dein Schutz bleibt also auch bei Server-Updates oder Lastverteilung lückenlos aktiv!
Fazit
Rate-Limiting ist kein Luxus, sondern eine Notwendigkeit für jede moderne API. Mit nur wenigen Zeilen Code und der Power von Redis hast du heute einen robusten Schutz gegen Spam-Bots und Bruteforce-Attacken gebaut. Deine Infrastruktur wird es dir durch Stabilität und niedrigere Kosten danken!
Login