Status
{
"requêtes effectuées": 2,
"requêtes restantes": 3,
"limite": 5,
"fenetre_temps": "1 minute"
}
Contenu de l'application express app.js
// ./app.js
const express = require('express');
const Redis = require('redis');
const fs = require('fs/promises')
require('dotenv').config()
const app = express();
// Création du client Redis
const redis = Redis.createClient({
username: 'default',
password: process.env.PASS,
socket: {
host: process.env.HOST,
port: process.env.PORT
}
});
// Gestion des événements Redis
redis.on('error', err => console.error('Erreur Redis:', err));
redis.on('connect', () => console.log('Redis connecté'));
// Connexion à Redis de manière asynchrone
(async () => {
await redis.connect();
})();
// Middleware de rate limiting
const rateLimiter = async (req, res, next) => {
const ip = req.ip;
const key = `ratelimit:${ip}:${Math.floor(Date.now() / 60000)}`;
try {
// Incrémenter le compteur pour cette IP
const numRequests = await redis.incr(key);
// Première requête : définir l'expiration
if (numRequests === 1) {
await redis.expire(key, 60);
}
// Limite de 5 requêtes par minute
if (numRequests > 5) {
return res.status(429).json({
error: 'Trop de requêtes. Veuillez réessayer plus tard.'
});
}
next();
} catch (err) {
console.error('Erreur Redis:', err);
next();
}
};
// Middleware pour voir le nombre de requêtes restantes
async function status (req, res, next) {
const ip = req.ip;
const key = `ratelimit:${ip}:${Math.floor(Date.now() / 60000)}`;
try {
const numRequests = await redis.get(key);
req.status = {
'requêtes effectuées': parseInt(numRequests) || 0,
'requêtes restantes': Math.max(5 - (parseInt(numRequests) || 0), 0),
limite: 5,
fenetre_temps: '1 minute'
};
} catch (err) {
req.status = { error: 'Erreur serveur' };
} finally {
next()
}
};
// Ici on applique le middleware à toutes les routes
// On aurait pu l'appliquer uniquement à une portion :
// ex : app.use('/api', rateLimiter);
app.use(rateLimiter);
// Route de test
app.get('/', status, async (req, res) => {
let indexContent = await fs.readFile('./index.html', { encoding: 'utf8' })
let thisFile = await fs.readFile('./app.js', { encoding: 'utf8' })
indexContent = indexContent.replace('splaceholder', JSON.stringify(req.status, null, 3))
indexContent = indexContent.replace('oplaceholder', thisFile)
res.set('content-type', 'text/html')
res.send(indexContent);
});
app.listen(3334);