Laravel Middleware em profundidade: Autenticação, Rate Limiting e Middleware personalizado
Dominar o middleware do Laravel com exemplos práticos: guards de autenticação, limitação de taxa com throttle, criação de middleware personalizado, atributos PHP no Laravel 13 e padrões avançados para aplicações em produção.

O middleware do Laravel funciona como uma camada de filtragem entre as requisições HTTP recebidas e a lógica da aplicação. Cada requisição percorre um pipeline de classes middleware antes de chegar a um controller, e cada resposta viaja de volta pelo mesmo pipeline. Compreender esse mecanismo é fundamental para construir aplicações Laravel seguras e de alto desempenho.
O middleware intercepta requisições HTTP antes que elas alcancem as rotas. O Laravel registra todos os middleware em bootstrap/app.php usando uma API fluente. Os middleware integrados gerenciam autenticação, proteção CSRF, gerenciamento de sessões e limitação de taxa nativamente.
Como funciona o pipeline de middleware no Laravel
O kernel HTTP do Laravel processa cada requisição através de uma pilha de middleware. Cada middleware recebe a requisição, executa sua lógica e então passa a requisição para a próxima camada via $next($request) ou interrompe o pipeline retornando uma resposta diretamente.
Essa arquitetura segue o padrão de projeto Chain of Responsibility. Um middleware pode atuar antes de a requisição alcançar o controller (por exemplo, verificações de autenticação), depois que a resposta é gerada (por exemplo, adicionando cabeçalhos), ou em ambos os momentos.
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;
class LogRequestTime
{
public function handle(Request $request, Closure $next): Response
{
$start = microtime(true); // Capture start time
$response = $next($request); // Pass to next middleware
$duration = microtime(true) - $start;
Log::info('Request completed', [
'url' => $request->url(),
'method' => $request->method(),
'duration' => round($duration * 1000, 2) . 'ms',
]);
return $response; // Return response up the stack
}
}Esse middleware envolve a requisição: ele registra o tempo de início antes do processamento e registra a duração depois que a resposta retorna. Esse padrão antes/depois é central no funcionamento dos middleware.
Middleware de autenticação: protegendo rotas
O Laravel inclui o alias de middleware auth, mapeado para Illuminate\Auth\Middleware\Authenticate. Ao aplicá-lo a uma rota, apenas usuários autenticados conseguem acessá-la. Usuários não autenticados recebem uma resposta 401 (API) ou são redirecionados para a página de login (web).
use App\Http\Controllers\DashboardController;
use App\Http\Controllers\ProfileController;
// Single route protection
Route::get('/dashboard', [DashboardController::class, 'index'])
->middleware('auth');
// Group protection for multiple routes
Route::middleware('auth')->group(function () {
Route::get('/profile', [ProfileController::class, 'show']);
Route::put('/profile', [ProfileController::class, 'update']);
Route::delete('/profile', [ProfileController::class, 'destroy']);
});Autenticação com múltiplos guards
Aplicações com vários tipos de usuários (painel administrativo, área do cliente, API) se beneficiam da autenticação baseada em guards. O middleware auth aceita um parâmetro de guard para especificar qual driver de autenticação deve ser utilizado.
// API routes use the 'sanctum' guard
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', fn (Request $request) => $request->user());
Route::apiResource('/orders', OrderController::class);
});
// routes/web.php
// Admin routes use a custom 'admin' guard
Route::middleware('auth:admin')->prefix('admin')->group(function () {
Route::get('/dashboard', [AdminController::class, 'index']);
Route::get('/users', [AdminController::class, 'users']);
});O parâmetro de guard após os dois pontos indica ao Laravel qual configuração de autenticação verificar. Essa abordagem mantém a lógica de autenticação organizada e separada entre as diferentes partes da aplicação.
O middleware guest é o inverso do auth, ele permite a passagem apenas de usuários não autenticados. Ao aplicá-lo às rotas de login e cadastro, impede-se que usuários já autenticados acessem essas páginas.
Limitação de taxa com o middleware Throttle
A limitação de taxa via middleware no Laravel protege as rotas contra abusos usando o middleware integrado throttle. Sua forma mais simples aceita dois parâmetros: o número máximo de requisições e a janela de tempo em minutos.
// Allow 60 requests per minute per user
Route::middleware('throttle:60,1')->group(function () {
Route::get('/posts', [PostController::class, 'index']);
Route::get('/posts/{post}', [PostController::class, 'show']);
});
// Stricter limit for write operations
Route::middleware(['auth:sanctum', 'throttle:10,1'])->group(function () {
Route::post('/posts', [PostController::class, 'store']);
Route::put('/posts/{post}', [PostController::class, 'update']);
});Rate limiters nomeados para controle avançado
Definir rate limiters nomeados no AppServiceProvider oferece controle granular sobre os limites com base no contexto do usuário. Essa abordagem é mais flexível do que os parâmetros throttle inline. Consultar a documentação oficial de limitação de taxa para opções adicionais.
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Http\Request;
public function boot(): void
{
// API rate limiter with tiered access
RateLimiter::for('api', function (Request $request) {
$user = $request->user();
if ($user?->hasSubscription('enterprise')) {
return Limit::perMinute(500)->by($user->id); // Enterprise: 500/min
}
if ($user) {
return Limit::perMinute(100)->by($user->id); // Authenticated: 100/min
}
return Limit::perMinute(20)->by($request->ip()); // Anonymous: 20/min
});
// Login limiter to prevent brute force
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)
->by($request->ip()) // Key by IP address
->response(function () { // Custom exceeded response
return response()->json([
'message' => 'Too many login attempts. Try again in a minute.',
], 429);
});
});
}A aplicação de limiters nomeados às rotas utiliza a sintaxe throttle:name:
Route::middleware('throttle:api')->group(function () {
Route::apiResource('/posts', PostController::class);
});
// routes/web.php
Route::middleware('throttle:login')
->post('/login', [AuthController::class, 'login']);O rate limiter escalonado acima demonstra um padrão de produção: usuários enterprise obtêm limites mais altos, usuários autenticados recebem limites moderados, e requisições anônimas são restringidas de forma agressiva. O método by() determina a chave de limitação, usando o ID do usuário para usuários autenticados e o endereço IP como fallback.
Pronto para mandar bem nas entrevistas de Laravel?
Pratique com nossos simuladores interativos, flashcards e testes tecnicos.
Criando middleware personalizado do zero
A criação de middleware personalizado cobre cenários que os middleware integrados não tratam. O comando Artisan make:middleware gera uma nova classe com a estrutura correta.
php artisan make:middleware EnsureUserHasRoleMiddleware de controle de acesso baseado em papéis
Um padrão comum de middleware personalizado aplica autorização baseada em papéis no nível da rota, aceitando nomes de papéis como parâmetros.
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class EnsureUserHasRole
{
public function handle(Request $request, Closure $next, string ...$roles): Response
{
$user = $request->user();
if (! $user || ! $user->hasAnyRole($roles)) {
abort(403, 'Insufficient permissions.');
}
return $next($request);
}
}O parâmetro variádico ...$roles permite passar múltiplos papéis separados por vírgulas. O registro e a utilização ficam assim:
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'role' => \App\Http\Middleware\EnsureUserHasRole::class,
]);
})
// routes/web.php
Route::middleware('role:admin')->group(function () {
Route::get('/admin', [AdminController::class, 'index']);
});
// Multiple roles: admin OR editor can access
Route::middleware('role:admin,editor')->group(function () {
Route::resource('/articles', ArticleController::class);
});Middleware de transformação de requisições
Um middleware pode modificar a requisição antes que ela alcance o controller. A seguir, um middleware para API JSON que impõe cabeçalhos de tipo de conteúdo e limpa as entradas do tipo string:
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class ApiRequestSanitizer
{
public function handle(Request $request, Closure $next): Response
{
// Reject non-JSON requests on API routes
if (! $request->expectsJson() && $request->isMethod('POST')) {
return response()->json(
['error' => 'Content-Type must be application/json'],
415
);
}
// Trim all string inputs
$input = $request->all();
array_walk_recursive($input, function (&$value) {
if (is_string($value)) {
$value = trim($value);
}
});
$request->merge($input);
return $next($request);
}
}Esse middleware cuida de duas responsabilidades: valida o tipo de conteúdo para requisições POST e sanitiza todas as entradas de texto removendo espaços em branco desnecessários.
Registro de middleware em bootstrap/app.php
O Laravel centraliza todo o registro de middleware no arquivo bootstrap/app.php. Essa abordagem substituiu o antigo app/Http/Kernel.php que existia antes do Laravel 11. A mesma API fluente funciona no Laravel 12 e 13.
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withMiddleware(function (Middleware $middleware) {
// Global middleware (runs on every request)
$middleware->append(
\App\Http\Middleware\LogRequestTime::class
);
// Add to the 'web' middleware group
$middleware->web(append: [
\App\Http\Middleware\TrackPageViews::class,
]);
// Add to the 'api' middleware group
$middleware->api(prepend: [
\App\Http\Middleware\ApiRequestSanitizer::class,
]);
// Register aliases for route-level use
$middleware->alias([
'role' => \App\Http\Middleware\EnsureUserHasRole::class,
'subscribed' => \App\Http\Middleware\EnsureUserIsSubscribed::class,
]);
// Control execution order
$middleware->priority([
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Auth\Middleware\Authenticate::class,
\App\Http\Middleware\EnsureUserHasRole::class,
]);
})
->create();O array priority é importante quando múltiplos middleware são atribuídos à mesma rota. O Laravel os ordena de acordo com essa lista, garantindo que a sessão seja iniciada antes da autenticação, e que a autenticação seja concluída antes das verificações de papel.
Os middleware são executados na ordem de registro. Para middleware de rota, o array priority sobrescreve a ordem padrão. A autenticação deve ser sempre posicionada antes da autorização para evitar verificar papéis em requisições não autenticadas.
Atributos PHP para middleware no Laravel 13
O Laravel 13 introduziu o atributo PHP #[Middleware] para declarar middleware diretamente em classes e métodos de controller. Essa abordagem mantém a configuração do middleware junto ao código que ele protege, tornando as regras de autorização mais legíveis e fáceis de manter.
namespace App\Http\Controllers;
use App\Models\Comment;
use App\Models\Post;
use Illuminate\Routing\Attributes\Controllers\Authorize;
use Illuminate\Routing\Attributes\Controllers\Middleware;
#[Middleware('auth')]
class CommentController
{
#[Middleware('subscribed')]
#[Authorize('create', [Comment::class, 'post'])]
public function store(Post $post)
{
// Only authenticated, subscribed users who can create comments reach here
}
public function index(Post $post)
{
// Still requires auth (from class-level attribute)
return $post->comments;
}
}O atributo #[Middleware('auth')] no nível da classe se aplica a todos os métodos. Os atributos no nível dos métodos se acumulam: store() requer tanto auth quanto subscribed. O atributo #[Authorize] se integra ao sistema de policies do Laravel, verificando as permissões antes da execução do método.
Essa abordagem baseada em atributos é opcional. Os middleware definidos em arquivos de rotas e o registro em bootstrap/app.php continuam totalmente suportados. Equipes que preferem definições de rota explícitas podem continuar usando a API fluente; equipes que desejam controllers autodocumentados podem adotar os atributos.
Middleware terminável para tarefas pós-resposta
O middleware terminável executa lógica após a resposta ter sido enviada ao cliente. Isso é particularmente útil para tarefas de logging, analytics ou limpeza que não devem bloquear o usuário.
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\Response;
class CollectAnalytics
{
public function handle(Request $request, Closure $next): Response
{
return $next($request); // Pass through without delay
}
public function terminate(Request $request, Response $response): void
{
// Runs after response is sent to client
DB::table('analytics')->insert([
'path' => $request->path(),
'method' => $request->method(),
'status_code' => $response->getStatusCode(),
'user_id' => $request->user()?->id,
'ip' => $request->ip(),
'created_at' => now(),
]);
}
}O método terminate recebe tanto a requisição original quanto a resposta final. Recomenda-se registrar esse middleware como singleton no AppServiceProvider para garantir que a mesma instância trate tanto handle() quanto terminate().
Padrões de middleware para produção
Diversos padrões de middleware aparecem consistentemente em aplicações Laravel em produção.
Bypass do modo de manutenção, permitir que IPs internos acessem a aplicação durante a manutenção:
class MaintenanceBypass
{
private array $allowedIps = ['192.168.1.0/24', '10.0.0.1'];
public function handle(Request $request, Closure $next): Response
{
if (app()->isDownForMaintenance()) {
foreach ($this->allowedIps as $ip) {
if ($request->ip() === $ip) {
return $next($request);
}
}
}
return $next($request);
}
}Cabeçalhos de segurança, adicionar HSTS, política de segurança de conteúdo e outros cabeçalhos a cada resposta:
class SecurityHeaders
{
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
$response->headers->set('X-Content-Type-Options', 'nosniff');
$response->headers->set('X-Frame-Options', 'SAMEORIGIN');
$response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');
$response->headers->set(
'Strict-Transport-Security',
'max-age=31536000; includeSubDomains'
);
return $response;
}
}Esses padrões ilustram as duas posições principais dos middleware: antes da requisição (o bypass de manutenção verifica o IP e potencialmente bloqueia o acesso) e depois da resposta (os cabeçalhos de segurança modificam a resposta de saída).
Pronto para mandar bem nas entrevistas de Laravel?
Pratique com nossos simuladores interativos, flashcards e testes tecnicos.
Fontes
- Documentação do Laravel sobre Middleware: referência oficial para registro de middleware, grupos e parâmetros
- Notas de versão do Laravel 13: anúncio do atributo
#[Middleware]e melhorias noPreventRequestForgery - Documentação do Laravel sobre Rate Limiting: facade RateLimiter, limiters nomeados e configuração do middleware throttle
Padrões de middleware Laravel para preparação de entrevistas
- O middleware do Laravel opera como um pipeline: cada classe processa a requisição, atua sobre ela e a passa adiante ou interrompe o fluxo com uma resposta
- O middleware
authprotege rotas com autenticação baseada em guards, suportando múltiplos tipos de usuários via sintaxeauth:guard - A limitação de taxa através do middleware
throttlee das definições nomeadasRateLimiter::for()permite controle de acesso escalonado com base no contexto do usuário - Os middleware personalizados tratam preocupações transversais como verificações de papel, sanitização de requisições e cabeçalhos de segurança sem sobrecarregar os controllers
- Todo o registro de middleware acontece em
bootstrap/app.phpusando uma API fluente, comprioritycontrolando a ordem de execução - O atributo
#[Middleware]do Laravel 13 permite declarar middleware diretamente nos controllers, mantendo as regras de autorização junto aos handlers - O middleware terminável executa tarefas pós-resposta (analytics, logging) sem impactar a latência percebida pelo usuário
- Os parâmetros de middleware via sintaxe
:parammantêm as definições de rota expressivas e as classes middleware reutilizáveis em diferentes contextos
Comece a praticar!
Teste seus conhecimentos com nossos simuladores de entrevista e testes tecnicos.
Você saberia encontrar o bug em Laravel?
Um trecho real, um bug escondido, uma tentativa por dia. Sem conta para testar.

Escrito por
Anthony Fillion-MailletFundador da SharpSkill
Desenvolvedor fullstack há mais de 10 anos. Dirige a SharpSkill e responde por tudo o que é publicado aqui.
Atualizado em 21 de setembro de 2026
Tags
Compartilhar
Artigos relacionados

Soluções Laravel: Padrões Avançados, Depuração e Perguntas de Entrevista 2026
Dominar soluções Laravel com padrões arquiteturais avançados, técnicas de depuração e conhecimentos essenciais para entrevistas. Classes de serviço, padrão Repository, depuração com Telescope e perguntas frequentes.

Laravel Livewire 3 em 2026: Aplicações Reativas e Perguntas de Entrevista
Domine Laravel Livewire 3 com este guia completo sobre componentes reativos, integração com Alpine.js, validação em tempo real e perguntas de entrevista técnica.

Testes no Laravel com Pest 5 em 2026: TIA, Mocking e Perguntas de Entrevista
Domine as melhores praticas de testes no Laravel com Pest 5, Test Impact Analysis, Mockery, fakes de facades e testes de arquitetura. Aborda testes unitarios, testes de feature, estrategias de mocking e perguntas comuns de entrevistas para desenvolvedores Laravel.