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);