PHP Profi

Ограничение скорости API в Laravel 5.2 Перевод Серия 

В последнее время всё больше и больше моих работ на Laravel связано с созданием API. У меня есть свой класс для ограничения скорости, который я использовал, но у меня было ощущение, что есть способ сделать это чище. Неудивительно, что, когда Тейлор решил написать middlewere ограничения скорости для Laravel, он сделал это чище и лучше, чем у меня.

Краткое введение в ограничение скорости

Если Вы незнакомы с ним, ограничения скорости — это инструмент, наиболее часто используемый в API, который ограничивает количество запросов за определённое время, которое любой человек (или ПО) могут сделать.

Это означает, что, например, если некий бот запрашивает какой-нибудь особо "тяжёлый" роут API, то ваше приложение не упадёт, т. к. после n-ной попытки он получит ответ 429: Too Many Attempts..

Обычно хорошо написанное приложение, которое реализует ограничение скорости, также отправляет три заголовка: X-RateLimit-Limit, X-RateLimit-Remaining, and Retry-After (вы получите только Retry-After, если вы достигли предела). В X-RateLimit-Limit содержится максимальное количество запросов, которое вы можете сделать этим приложение за текущий период времени. В X-RateLimit-Remaining — сколько запросов у вас осталось. И в Retry-After — через сколько секунд вы можете отправить запрос ещё раз (Retry-After также может содержать дату вместо количества секунд).

Примечание: каждое API выбирает свой промежуток времени для ограничения скорости. У GitHub это час, у Twitter — 15 минут. Этот middleware для Laravel имеет промежуток в минуту.

Как использовать middleware Laravel'а для ограничения скорости

Итак, о новой функции в фреймворк laravel 5.2. Есть новый middleware throttle, который вы можете использовать для этого. Давайте взглянем на нашу группу роутов для API:

Route::group(['prefix' => 'api'], function () {
    Route::get('people', function () {
        return Person::all();
    });
});

Давайте применим throttle к ней. По умолчанию стоит ограничение в 60 запросов в минуту и по достижению лимита доступ отключается до конца истечения минуты.

Route::group(['prefix' => 'api', 'middleware' => 'throttle'], function () {
    Route::get('people', function () {
        return Person::all();
    });
});

Если вы сделаете запрос этому роуту api/people, то вы увидите следующие строки в заголовках ответа:

HTTP/1.1 200 OK
... другие заголовки ...
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59

Этот ответ означает следующее:

A) этот запрос завершился успешно (статус 200)
B) вы можете запрашивать этот роут 60 раз в минуту
C) у вас осталось 59 запросов на данную минуту

Какой ответ мы получим, если мы вышли за ограничение скорости?

HTTP/1.1 429 Too Many Requests
... другие заголовки ...
Retry-After: 60
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0

А сам ответ будет содержать строку: "Too Many Attempts."

Что, если бы мы попробовали еще раз через 30 секунд?

HTTP/1.1 429 Too Many Requests
... другие заголовки ...
Retry-After: 30
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0

Тот же ответ, за исключением того, что таймер Retry-After, который сообщает нам как долго ждать, опустился на 30 секунд.

Настройка middleware throttle

Давайте сделаем немного настройки. Допустим, мы хотим ограничить его до 5 попыток в минуту:

Route::group(['prefix' => 'api', 'middleware' => 'throttle:5'], function () {
    Route::get('people', function () {
        return Person::all();
    });
});

И если мы хотим изменить его таким образом, что если кто-то достигает предела, он не может снова отправить запрос в течение:

Route::group(['prefix' => 'api', 'middleware' => 'throttle:5,10'], function () {
    Route::get('people', function () {
        return Person::all();
    });
});

Вот и все!

Код, которые это реализует, вы можете помотреть здесь: ThrottlesRequests.php

2016-08-30 оригинал

Последние посты

Комментарии

авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий