Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
July 19, 2022 09:19 pm GMT

Quer limitar o nmero de requisies na sua api?

Neste artigo vou mostrar a implementao de um middleware que controla a quantidade de requisies em uma rota ou grupo de rotas.

Deixo claro que este artigo tem fins educacionais e ele no deve ser a nica forma de controlar o acesso api.

Apresentao do cenrio

Controlar a quantidade de requisies que sua aplicao recebe uma estratgia interessante porque evita excessos por parte das aplicaes cliente.

Imaginando um cenrio onde nossa aplicao tem informaes atualizadas sobre emisso de documentos oficiais, ela receber requisies de muitas aplicaes ao mesmo tempo com o objetivo de atualizar seus prprios sistemas.

Este cenrio bastante comum.

Ocorre que, dado o grande volume de informaes que precisam ser processadas, nossa aplicao levar um certo tempo para responder a cada requisio.

Dentre as aplicaes que esto acessando nosso servio h uma que faz requisies a cada 5 segundos.

Realizando uma conta rpida, essa aplicao sozinha far 12 requisies por minuto, 720 por hora e 17 mil por dia.

Para evitar excessos e no prejudicar as outras aplicaes vamos implementar um bloqueio para aplicaes que fizerem mais de 5 requisies por minuto.

Ferramentas necessrias

Existem instaladores que trazem embutidos o PHP, MySQL e Apache (servidor web), como WAMPSERVER, XAMPP e Laragon. Deixo a seu critrio a escolha de alguns desses pacotes, ou outro que seja familiar a voc.

Para o editor de textos estou utilizando o Visual Studio Code. Alm de ser gratuito possibilita a instalao de diversas extenses.

Projeto

O projeto a ser desenvolvido uma aplicao Laravel conhecido framework de desenvolvimento web e est, no momento em que escrevo este artigo, na verso 9.

Acessando o terminal de sua preferncia, vamos digitar o seguinte comando:

composer create-project --prefer-dist laravel/laravel ratelimit

O tempo de concluso desta etapa pode variar de acordo com a velocidade de conexo internet e a configurao do computador.

Assim que esta etapa for concluda precisamos acessar o diretrio do projeto.

Middleware

Dentro do diretrio do projeto, vamos criar o middleware com o seguinte comando:

php artisan make:middleware CustomRateLimit

Por padro em aplicaes Laravel o middleware criado com este comando ser salvo em App\Http\Middleware.

Utilizando o editor de textos da sua preferncia vamos codificar o mtodo handle() conforme a seguir:

<?phpnamespace App\Http\Middleware;use Closure;use Illuminate\Http\Request;use Illuminate\Support\Facades\RateLimiter;class CustomRateLimit{    /**     * Handle an incoming request.     *     * @param  \Illuminate\Http\Request  $request     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse     */    public function handle(Request $request, Closure $next)    {        $executed = RateLimiter::attempt(            'education'.$request->ip(),            $perMinute = 5,            function() {            }        );        if (!$executed) {            return response(                [                    'message' => 'Too many attempts.. try again in '.RateLimiter::availableIn('education').' seconds'                ], 429);        }        return $next($request);    }}

Explicando o cdigo, criamos um limitador de requisies atravs do construtor attempt que possui 3 parmetros obrigatrios e 1 parmetro opcional.

O primeiro parmetro recebe o nome do limitador.

Este nome deve ser nico e para atender esta necessidade vamos concatenar o texto 'education' com o ip obtido atravs da varivel $request.

OBS.: a classe Illuminate\Http\Request encapsula todas as informaes de uma requisio http durante seu ciclo de vida.

No segundo parmetro do construtor attemptinformamos o limite de requisies por minuto.

O terceiro parmetro recebe uma funo de callback. A implementao desta funo no obrigatria para validao das requisies. Neste caso, informamos somente o cabealho do mtodo, sem implementao.

O ltimo parmetro opcional. Nele alteramos o intervalo, em segundos, para verificar as requisies de entrada.

Por exemplo, se quisermos bloquear por 5 minutos, o valor a ser informado nesse parmetro ser 300, ou 60 segundos vezes 5 minutos.

Controller

Continuando, vamos criar uma controller.

php artisan make:controller RateLimitController

Por padro as controllers criadas com o comando acima ficam salvas em App\Http\Controllers.

Editando a controller vamos implementar um mtodo para reiniciar o contador de requisies, desbloqueando o acesso aplicao cliente e retornando uma mensagem customizada.

<?phpnamespace App\Http\Controllers;use Illuminate\Http\Request;use Illuminate\Support\Facades\RateLimiter;class RateLimitController extends Controller{    public function clearLimit(Request $request)    {        RateLimiter::clear('education'.$request->ip());        return response(['message' => 'Attempts cleared for '.$request->ip()], 200);    }}

Explicando o cdigo, fazemos uma chamada para o mtodo clear() que recebe como parmetro o nome do limitador.

Perceba que o nome o mesmo informado na implementao do mtodo handle(Request $request, Closure $next) do middleware.

Rota

Agora vamos abrir o arquivo de rotas, adicionando duas novas rotas.

<?phpuse Illuminate\Http\Request;use Illuminate\Support\Facades\Route;use App\Http\Middleware\CustomRateLimit;use App\Http\Controllers\RateLimitController;Route::middleware([CustomRateLimit::class])->get('/rate-limit', function() {    $date = new \DateTime();    $date->setTimezone(new \DateTimeZone('-0300'));    return $date->format('Y-m-d H:i:s');});Route::post('/rate-limit/clear', [RateLimitController::class, 'clearLimit']);

A primeira rota serve para incrementarmos o nmero de requisies de forma a atingir o limite que estabelecemos no middleware.

Assim que o limite for alcanado mostraremos uma mensagem customizada informando quanto tempo (em segundos) falta para que o aplicao cliente possa fazer novas requisies.

A segunda rota tem como objetivo zerar o contador atravs de uma chamada para o mtodo clearLimit() da controller RateLimitController.

Testando

Acessando novamente o terminal de sua preferncia, na pasta do projeto, vamos iniciar o servidor na porta 8108.

Dica: dentro do VSCode, utilizando a combinao de teclas Ctrl+' um terminal ser aberto na parte inferior da IDE, j na pasta do projeto.

php artisan serve --port=8108

Utilizando a extenso Thunder para VSCode, vamos fazer requisies na primeira rota at o limite de tentativas ser atingido.

E em seguida, vamos fazer uma requisio para a rota que reinicia o contador de tentativas.

Observaes

Por padro, aplicaes Laravel tem o cache pr configurado para arquivo.

Entretanto possvel mudar a configurao para uso com bancos de dados, Memcached ou Redis, alterando a chave 'default' da classe
Config\Cache.php.

Concluso

O objetivo deste artigo foi mostrar como implementar uma forma de evitar excessos ao acessar sua aplicao, bloqueando temporariamente algumas aplicaes sem parar o servio e nem prejudicar outras aplicaes.

Reforo que esta abordagem no deve ser tratada como nica opo de segurana para sua aplicao

Obrigado pela leitura e at breve.

Extenses utilizadas

Em desenvolvimento web, uma boa ferramenta para testar requisies api faz toda diferena.
Por isso deixo aqui o link para a extenso para VSCode Thunder RESTClient.

A extenso gratuita e bem robusta.

J para aplicaes Laravel, a extenso Laravel Extra Intellisense ajuda muito na incluso automtica de referncias.

Repositrio pblico

O projeto est publicado no github neste repositrio.


Original Link: https://dev.to/marciopolicarpo/quer-limitar-o-numero-de-requisicoes-na-sua-api-532n

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To