De plus en plus de mon travail à Laravel ces derniers temps a été de créer des API. J’ai une classe de limiteur de débit manuel que j’utilise, mais j’ai eu le sentiment qu’il existe une façon plus propre de le faire. Sans surprise, lorsque Taylor a entrepris d’écrire un middleware limiteur de débit pour Laravel, il l’a fait plus proprement et mieux que moi.
Brève introduction à la limitation de débit
Si vous ne le connaissez pas, la limitation de débit est un outil, le plus souvent utilisé dans les API, qui limites le taux auquel tout demandeur individuel peut faire des demandes.
Cela signifie, par exemple, que si un bot atteint mille fois par minute une route d’API particulièrement coûteuse, votre application ne plantera pas, car après le nième essayez, ils obtiendront plutôt un 429: Too Many Attempts.
réponse du serveur.
Habituellement, une application bien écrite qui implémente la limitation de débit retransmettra également trois en-têtes qui pourraient ne pas être sur une autre application : X-RateLimit-Limit
, X-RateLimit-Remaining
et Retry-After
(vous n’obtiendrez que Retry-After
si vous avez atteint la limite). X-RateLimit-Limit
vous indique le nombre maximum de requêtes que vous êtes autorisé à faire pendant la période de cette application, X-RateLimit-Remaining
vous indique le nombre de demandes qu’il vous reste dans cette période actuelle, et Retry-After
vous indique combien de secondes attendre avant de réessayer. (Retry-After
peut également être une date au lieu d’un nombre de secondes).
Remarque : Chaque API choisit la période pour laquelle elle limite le débit. GitHub est par heure, Twitter est par segment de 15 minutes. Ce middleware Laravel est à la minute.
Comment utiliser le middleware de limitation de débit de Laravel
Passons donc à la nouvelle fonctionnalité de Laravel 5.2. Il y a un nouveau throttle
middleware que vous pouvez utiliser. Jetons un coup d’œil à notre groupe d’API :
Route::group(['prefix' => 'api'], function () {
Route::get('people', function () {
return Person::all();
});
});
Appliquons-y un accélérateur. L’accélérateur par défaut le limite à 60 tentatives par minute et désactive leur accès pendant une seule minute s’ils atteignent la limite.
Route::group(['prefix' => 'api', 'middleware' => 'throttle'], function () {
Route::get('people', function () {
return Person::all();
});
});
Si vous faites une demande à ce api/people
route, vous verrez maintenant les lignes suivantes dans les en-têtes de réponse :
HTTP/1.1 200 OK
... other headers here ...
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
N’oubliez pas que cette réponse signifie :
A) Cette requête a réussi (le statut est 200
)
B) Vous pouvez essayer cet itinéraire 60 fois par minute
C) Il vous reste 59 requêtes pour cette minute
Quelle réponse obtiendrions-nous si nous dépassions la limite de taux ?
HTTP/1.1 429 Too Many Requests
... other headers here ...
Retry-After: 60
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
Et le contenu réel de la réponse serait une chaîne : “Trop de tentatives”.
Et si on réessayait après 30 secondes ?
HTTP/1.1 429 Too Many Requests
... other headers here ...
Retry-After: 30
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
Même réponse, sauf le Retry-After
la minuterie qui nous indique combien de temps attendre a diminué de 30 secondes.
Personnaliser le throttle
middleware
Faisons un peu de personnalisation. Nous voulons le limiter à 5 tentatives par minute.
Route::group(['prefix' => 'api', 'middleware' => 'throttle:5'], function () {
Route::get('people', function () {
return Person::all();
});
});
Et si nous voulons le changer pour que, si quelqu’un atteint la limite, il ne puisse pas réessayer avant 10 minutes ?
Route::group(['prefix' => 'api', 'middleware' => 'throttle:5,10'], function () {
Route::get('people', function () {
return Person::all();
});
});
C’est tout ce qu’on peut en dire!
Vous pouvez voir le code qui prend en charge ceci ici : ThrottlesRequests.php