La limitation du débit est essentielle pour protéger les ressources d’une application ou d’un site web contre une utilisation excessive ou inappropriée. Qu’elle résulte d’une intervention humaine malveillante, d’une attaque de robots ou d’une vulnérabilité négligée, l’utilisation abusive des ressources peut entraver l’accès légitime à votre application et introduire de graves vulnérabilités.

Cet article explique comment ajouter une limitation de taux à une API dans une application Laravel.

Limitez le trafic de votre API dans Laravel

La limitation de débit est un mécanisme conçu pour atténuer l’exploitation des ressources de votre application. Bien qu’il ait de nombreuses utilisations, il est particulièrement utile pour les API publiques dans les grands systèmes évolutifs. Elle garantit que tous les utilisateurs légitimes conservent un accès équitable aux ressources du système.

La limitation de débit est également cruciale pour la sécurité, le contrôle des coûts et la stabilité générale du système. Elle peut aider à prévenir les attaques basées sur les requêtes, telles que les attaques par déni de service distribué (DDoS). Cette attaque repose sur l’envoi de requêtes répétées pour submerger et perturber l’accès à une application ou à un serveur de site web.

Il existe plusieurs méthodes pour mettre en œuvre la limitation de débit. Vous pouvez utiliser des variables qui caractérisent le demandeur pour déterminer qui peut accéder à votre application et à quelle fréquence. Les variables les plus courantes sont les suivantes

  • Adresse IP – La mise en œuvre de limites de taux basées sur les adresses IP vous permet de restreindre le nombre de requêtes par adresse. Cette méthode est particulièrement utile lorsque les utilisateurs peuvent accéder à une application sans fournir d’informations d’identification.
  • Clé API – Limiter l’accès via des clés API consiste à fournir au demandeur des clés API pré-générées et à établir des limites de taux par clé. Avec cette approche, vous pouvez également appliquer différents niveaux d’accès aux clés API générées.
  • ID client – Vous pouvez également prégénérer un ID client qu’un utilisateur peut intégrer dans l’en-tête ou le corps des requêtes d’API. Cette méthode vous permet de définir des niveaux d’accès par ID afin de garantir qu’aucun client ne puisse monopoliser les ressources du système.

Middleware Laravel

Le middleware fournit un mécanisme pratique pour inspecter et filtrer les requêtes HTTP entrant dans une application. Il s’agit essentiellement d’une couche de code entre l’application et son infrastructure sous-jacente pour permettre la communication entre ses ressources.

Comment mettre en place des limites de débit

Ce tutoriel utilise une mini-bibliothèque API existante sur le framework Laravel 10 pour démontrer l’utilisation de Laravel Throttle. L’exemple de projet de départ contient les implémentations CRUD (create, read, update, delete) de base nécessaires pour gérer les livres dans une collection et deux routes supplémentaires pour démontrer certains concepts de limitation de taux.

Pré-requis

Ce tutoriel suppose que vous êtes familier avec les bases du développement d’API dans Laravel. Assurez-vous que vous disposez des éléments suivants :

Vous utilisez également MyKinsta pour configurer et déployer cette API. Vous pouvez suivre le modèle de projet fourni et prévisualiser le résultat final à partir du code source complet.

Configuration de l’application Laravel

  1. Pour commencer, clonez le modèle de projet.
  2. Ensuite, créez un fichier .env dans le répertoire racine du projet et copiez-y le contenu de .env.example.
  3. Ensuite, terminez l’installation en utilisant les commandes suivantes pour installer les dépendances de l’application et générer la clé d’application.
composer install
php artisan key:generate

Si cette commande n’ajoute pas automatiquement la clé d’application à votre fichier .env, exécutez php artisan key:generate --show, copiez la clé générée et collez-la dans votre fichier .env comme valeur pour APP_KEY.

  1. Une fois l’installation des dépendances et la génération de la clé d’application terminées, démarrez l’application à l’aide de la commande suivante :
php artisan serve

Cette commande démarre l’application et la rend accessible via le navigateur à l’adresse https://127.0.0.1:8000.

  1. Visitez l’URL pour confirmer que la page de bienvenue de Laravel s’affiche :

L'écran de bienvenue de Laravel
L’écran de bienvenue de Laravel

Configuration de la base de données

Configurons et mettons en place la base de données de l’application dans MyKinsta.

  1. Naviguez vers le tableau de bord de votre compte MyKinsta et cliquez sur le bouton Ajouter un service:

Tableau de bord MyKinsta avec plusieurs services configurés.
Tableau de bord MyKinsta avec plusieurs services configurés.

  1. Dans la liste Ajouter un service, cliquez sur Base de données et configurez les paramètres pour démarrer votre instance de base de données :

Configuration de la base de données MyKinsta.
Configuration de la base de données MyKinsta.

Ce tutoriel utilise MariaDB, mais vous pouvez choisir n’importe quelle option de base de données supportée par Laravel que Kinsta fournit.

  1. Une fois que vous avez saisi les détails de votre base de données, cliquez sur le bouton Continuer pour finaliser le processus.

Les bases de données provisionnées sur Kinsta ont des réglages de connexion internes et externes. Vous devez utiliser les paramètres de connexion internes pour les applications hébergées dans le même compte Kinsta et les paramètres externes pour les connexions externes. Par conséquent, utilisez les informations d’identification de la base de données externe de Kinsta pour votre application.

  1. Copiez et mettez à jour les informations d’identification .env de la base de données de l’application avec les informations d’identification externes indiquées dans la capture d’écran ci-dessous :

Détails de la configuration de la base de données MyKinsta.
Détails de la configuration de la base de données MyKinsta.

DB_CONNECTION=mysql
DB_HOST=your_host_name
DB_PORT=your_port
DB_DATABASE=your_database_info
DB_USERNAME=your_username
DB_PASSWORD=your_password
  1. Après avoir rempli les informations d’identification de la base de données, testez la connexion en appliquant la migration de la base de données à l’aide de la commande ci-dessous :
php artisan migrate

Si tout fonctionne correctement, vous devriez obtenir une réponse similaire à celle présentée ci-dessous.

Migration réussie de la base de données sur un terminal.
Migration réussie de la base de données sur un terminal.

  1. Ensuite, utilisez la commande suivante pour lister les itinéraires d’application et voir les itinéraires déjà mis en œuvre.
php artisan route:list

Vous devriez maintenant voir les points de terminaison de l’API disponibles :

Application route list sur le terminal.
Application route list sur le terminal.

  1. Lancez l’application et vérifiez que tout fonctionne toujours correctement. Vous pouvez tester ces points d’accès via le terminal à l’aide d’un outil comme Postman ou CURL.

Comment limiter le débit dans une application Laravel

Plusieurs techniques de limitation de débit sont disponibles pour les applications Laravel. Vous pouvez bloquer un ensemble d’adresses IP ou appliquer des limites de requêtes basées sur la durée en fonction de l’adresse IP ou de l’identifiant de l’utilisateur. Ensuite, vous appliquerez chacune de ces méthodes.

  1. Installez le paquet Laravel Throttle à l’aide de la commande suivante :
composer require "graham-campbell/throttle:^10.0"
  1. Vous pouvez également apporter des modifications supplémentaires aux configurations de Laravel Throttle en publiant le fichier vendor configurations:
php artisan vendor:publish --provider="GrahamCampbell\Throttle\ThrottleServiceProvider"

Comment bloquer des adresses IP

Une technique de limitation du débit vous permet de bloquer les requêtes provenant d’un ensemble spécifique d’adresses IP.

  1. Pour commencer, créez l’intergiciel nécessaire :
php artisan make:middleware RestrictMiddleware
  1. Ensuite, ouvrez le fichier d’intergiciel app/Http/Middleware/RestrictMiddleware.php créé et remplacez le code de la fonction handle par l’extrait ci-dessous. Assurez-vous d’ajouter use App; à la liste des importations en haut du fichier.
$restrictedIps = ['127.0.0.1', '102.129.158.0'];
if(in_array($request->ip(), $restrictedIps)){
  App::abort(403, 'Request forbidden');
}
return $next($request);
  1. Dans le fichier app/Http/Kernel.php, créez un alias pour cette application middleware en mettant à jour le tableau middlewareAliases comme suit :
    protected $middlewareAliases = [
    . . .
    'custom.restrict' => App\Http\Middleware\Restrict\Middleware::class,
    ];
    1. Ensuite, appliquez cet intergiciel à l’adresse /restricted-route dans le fichier routes/api.php comme suit et testez :
    Route::middleware(['custom.restrict'])->group(function () {
      Route::get('/restricted-route', [BookController::class, 'getBooks']);
    });

    Lorsqu’il fonctionne correctement, cet intergiciel bloque toutes les requêtes provenant des IP du tableau $restrictedIps: 127.0.0.1 et 102.129.158.0. Les requêtes provenant de ces IP renvoient une réponse 403 Forbidden, comme indiqué ci-dessous :

    Une réponse 403 Forbidden pour le point d'accès GET /restricted-route sur Postman
    Une réponse 403 Forbidden pour le point d’accès GET /restricted-route sur Postman

    Comment limiter les requêtes par adresse IP

    Ensuite, vous pouvez limiter les requêtes en fonction de l’adresse IP de l’utilisateur.

    1. Appliquez l’intergiciel Throttle aux routes GET et PATCH du point d’accès /book dans routes/api.php:
    Route::middleware(['throttle:minute'])->group(function () {
      Route::get('/book', [BookController::class, 'getBooks']);
    });
    
    Route::middleware(['throttle:5,1'])->group(function () {
      Route::patch('/book', [BookController::class, 'updateBook']);
    });
    1. Vous devez également mettre à jour la fonction configureRateLimiting dans le fichier app/Providers/RouteServiceProvider avec l’intergiciel que vous avez ajouté aux routes ci-dessus.
    … 
    RateLimiter::for('minute', function (Request $request) {
      return Limit::perMinute(5)->by($request->ip());
    });

    Cette configuration limite les requêtes vers le point de terminaison /book GET à 5 par minute, comme indiqué ci-dessous.

    Une réponse 429 Too Many Requests pour le point d'accès /book GET sur Postman.
    Une réponse 429 Too Many Requests pour le point d’accès /book GET sur Postman.

    Comment limiter les requêtes en fonction de l’identifiant de l’utilisateur et des sessions

    1. Pour limiter le débit en utilisant les paramètres user_id et session, mettez à jour la fonction configureRateLimiting dans le fichier app/Providers/RouteServiceProvider avec les limiteurs et variables supplémentaires suivants :
    ...
    RateLimiter::for('user', function (Request $request) {
      return Limit::perMinute(10)->by($request->user()?->id ?: $request->ip());
    });
    RateLimiter::for('session', function (Request $request) {
      return Limit::perMinute(15)->by($request->session()->get('key') ?: $request->ip());
    });
    1. Enfin, appliquez ce code aux routes /book/{id} GET et /book POST dans le fichier routes/api.php:
    Route::middleware(['throttle:user'])->group(function () {
      Route::get('/book/{id}', [BookController::class, 'getBook']);
    });
    Route::middleware(['throttle:session'])->group(function () {
      Route::post('/book', [BookController::class, 'createBook']);
    });

    Ce code limite les requêtes utilisant user_id et session, respectivement.

    Méthodes supplémentaires dans Throttle

    Laravel Throttle propose plusieurs méthodes supplémentaires pour un meilleur contrôle de votre implémentation de limitation de taux. Ces méthodes sont les suivantes :

    • attempt – Accède au point de terminaison, incrémente le nombre d’occurrences et renvoie un booléen indiquant si la limite d’occurrences configurée a été dépassée.
    • hit – Touche le Throttle, incrémente le nombre de hits et renvoie $this pour permettre un autre appel de méthode (facultatif).
    • clear – Réinitialise le compte Throttle à zéro et renvoie $this afin que vous puissiez effectuer un autre appel de méthode si vous le souhaitez.
    • count – Renvoie le nombre total d’occurrences du Throttle.
    • check – Renvoie un booléen indiquant si la limite d’accès au Throttle a été dépassée.
    1. Pour explorer la limitation de débit à l’aide de ces méthodes, créez une application middleware appelée CustomMiddleware à l’aide de la commande ci-dessous :
    php artisan make:middleware CustomMiddleware
    1. Ensuite, ajoutez les fichiers d’importation suivants au fichier middleware nouvellement créé dans app/Http/Middleware/CustomMiddleware.php:
    use GrahamCampbell\Throttle\Facades\Throttle;
    use App;
    1. Ensuite, remplacez le contenu de la méthode handle par l’extrait de code suivant :
    $throttler = Throttle::get($request, 5, 1);
    Throttle::attempt($request);
    if(!$throttler->check()){
      App::abort(429, 'Too many requests');
    }
    return $next($request);
    1. Dans le fichier app/Http/Kernel.php, créez un alias pour cette application middleware en mettant à jour le tableau middlewareAliases comme suit.
    protected $middlewareAliases = [
    . . .
    'custom.throttle' => \App\Http\Middleware\CustomMiddleware::class, 
    ];
    1. Ensuite, appliquez cet intergiciel à l’adresse /custom-route dans le fichier routes/api.php:
    Route::middleware(['custom.throttle'])->group(function () {
      Route::get('/custom-route', [BookController::class, 'getBooks']);
    });

    L’intergiciel personnalisé qui vient d’être implémenté vérifie si la limite de l’étranglement a été dépassée à l’aide de la commande check method. If the limit is exceeded, it responds with a 429 error. Otherwise, it allows the request to continue.

    Comment déployer l’application sur le serveur Kinsta

    Maintenant que vous avez exploré comment mettre en œuvre la limitation de débit dans une application Laravel, déployez l’application sur le serveur Kinsta pour la rendre accessible globalement.

    1. Commencez par pousser le code mis à jour sur GitHub, GitLab ou Bitbucket.
    2. Depuis votre tableau de bord Kinsta, cliquez sur le bouton Ajouter un service et sélectionnez Application dans la liste. Liez votre compte Git à votre compte Kinsta et sélectionnez le bon dépôt à déployer.
    3. Sous Détails de base, nommez l’application et choisissez votre centre de données préféré. Assurez-vous également d’avoir ajouté les variables d’environnement nécessaires à l’application. Celles-ci correspondent aux variables présentes dans votre fichier .env local : les variables de configuration APP_KEY et de la base de données.

    Détails de l'application sur MyKinsta.
    Détails de l’application sur MyKinsta.

    1. Cliquez sur le bouton Continuer pour sélectionner les variables de l’environnement de construction. Vous pouvez laisser les valeurs par défaut, car Kinsta remplit automatiquement les paramètres nécessaires.
    2. Sur l’onglet Processus, vous pouvez laisser les valeurs par défaut ou entrer un nom pour votre processus. Vous pouvez également sélectionner les tailles de pod et d’instance sur cet onglet.
    3. Enfin, l’onglet Paiement affiche un résumé de vos sélections. Ajoutez votre option de paiement préférée pour finaliser le processus.
    4. Une fois le processus terminé, cliquez sur l’onglet Applications pour afficher la liste des applications déployées.
    5. Cliquez sur le nom de l’application pour afficher les détails de son déploiement, comme indiqué ci-dessous. Vous pouvez utiliser l’URL de l’application pour y accéder.

    Détails du déploiement sur le tableau de bord MyKinsta.
    Détails du déploiement sur le tableau de bord MyKinsta.

    Comment tester l’application

    1. Pour tester l’application localement, utilisez la commande php artisan serve.

    Cette commande rend le navigateur de votre application accessible sur http://localhost:8000. Vous pouvez tester les points d’extrémité de l’API pour lesquels vous avez implémenté la limitation de débit en effectuant des appels répétés pour déclencher la fonctionnalité de limitation de débit.

    Le serveur Kinsta affiche une réponse Accès interdit parce que vous n’avez pas ajouté les détails de configuration qui indiquent à Kinsta comment servir l’application. Ajoutez ces détails maintenant.

    1. Créez un fichier .htaccess dans le répertoire racine de votre application et ajoutez-y le code suivant :
     <IfModule mod_rewrite.c>
      RewriteEngine On
      RewriteRule ^(.*)$ public/$1 [L]
    </IfModule>
    1. Poussez ces changements sur GitHub et Kinsta se déploie automatiquement pour mettre en œuvre le changement.
    2. Maintenant, ouvrez l’application en utilisant l’URL fournie et assurez-vous que vous voyez la page de bienvenue de Laravel.

    Vous pouvez maintenant tester les points d’extrémité de l’API pour lesquels vous avez mis en œuvre la limitation de taux à l’aide de Postman en effectuant des appels répétés jusqu’à ce que vous ayez atteint la limite configurée. Vous recevez une réponse 429 Too Many Requests après avoir dépassé la limite.

    Résumé

    L’intégration de fonctionnalités de limitation de débit dans une API Laravel permet de contrôler la vitesse à laquelle les utilisateurs consomment les ressources d’une application. La limitation du taux vous aide à fournir une expérience utilisateur fiable sans sous-dépenser ni sur-dépenser. Elle permet également de s’assurer que l’infrastructure sous-jacente de l’application reste fonctionnelle et efficace.

    Vous pouvez également consulter le blog de Kinsta pour en savoir plus sur d’autres concepts passionnants concernant Laravel et d’autres technologies web. Les services d’hébergement abordables et transparents sont fortement recommandés pour les besoins de votre application et de votre équipe.

Marcia Ramos Kinsta

I'm the Editorial Team Lead at Kinsta. I'm a open source enthusiast and I love coding. With more than 7 years of technical writing and editing for the tech industry, I love collaborating with people to create clear and concise pieces of content and improve workflows.