Laravel Middleware od podstaw: Uwierzytelnianie, Rate Limiting i własne middleware
Kompleksowy przewodnik po middleware w Laravel - od uwierzytelniania i rate limitingu po tworzenie własnych klas middleware. Praktyczne przykłady kodu i wzorce produkcyjne.

Middleware w Laravel pełni rolę warstwy filtrującej pomiędzy przychodzącymi żądaniami HTTP a logiką aplikacji. Każde żądanie przechodzi przez potok klas middleware zanim dotrze do kontrolera, a każda odpowiedź wraca tą samą drogą. Zrozumienie tego mechanizmu jest niezbędne do budowania bezpiecznych i wydajnych aplikacji Laravel w 2026 roku.
Middleware przechwytuje żądania HTTP zanim dotrą do tras. Laravel 12 rejestruje wszystkie middleware w pliku bootstrap/app.php za pomocą płynnego API. Wbudowane middleware obsługują uwierzytelnianie, ochronę CSRF, zarządzanie sesjami i rate limiting od razu po instalacji.
Jak działa potok middleware w Laravel
Jądro HTTP Laravela przetwarza każde żądanie przez stos middleware. Każde middleware otrzymuje żądanie, wykonuje swoją logikę, a następnie przekazuje żądanie do następnej warstwy za pomocą $next($request) lub przerywa potok, zwracając odpowiedź bezpośrednio.
Ta architektura wykorzystuje wzorzec Chain of Responsibility. Middleware może działać przed dotarciem żądania do kontrolera (np. sprawdzanie uwierzytelniania), po wygenerowaniu odpowiedzi (np. dodawanie nagłówków) lub w obu przypadkach jednocześnie.
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
}
}To middleware opakowuje żądanie: rejestruje czas rozpoczęcia przed przetwarzaniem i loguje czas trwania po otrzymaniu odpowiedzi. Ten wzorzec przed/po stanowi podstawę działania middleware.
Middleware uwierzytelniania: Ochrona tras
Laravel dostarcza alias middleware auth, powiązany z Illuminate\Auth\Middleware\Authenticate. Zastosowanie go do trasy zapewnia, że tylko uwierzytelnieni użytkownicy mogą uzyskać do niej dostęp. Nieuwierzytelnieni użytkownicy otrzymują odpowiedź 401 (API) lub zostają przekierowani na stronę logowania (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']);
});Uwierzytelnianie z wieloma guardami
Aplikacje z wieloma typami użytkowników (panel administracyjny, strefa klienta, API) korzystają z uwierzytelniania opartego na guardach. Middleware auth przyjmuje parametr guard określający, który sterownik uwierzytelniania ma zostać użyty.
// 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']);
});Parametr guard po dwukropku informuje Laravel, wobec której konfiguracji uwierzytelniania należy dokonać weryfikacji. Dzięki temu logika uwierzytelniania pozostaje czysta i odseparowana w różnych częściach aplikacji.
Middleware guest jest odwrotnością auth — przepuszcza tylko nieuwierzytelnionych użytkowników. Zastosowanie go do tras logowania i rejestracji uniemożliwia zalogowanym użytkownikom ponowny dostęp do tych stron.
Rate Limiting z middleware Throttle
Rate limiting w Laravel chroni trasy przed nadużyciami za pomocą wbudowanego middleware throttle. Najprostsza forma przyjmuje dwa parametry: maksymalną liczbę żądań i okno czasowe w minutach.
// 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']);
});Nazwane Rate Limitery dla zaawansowanej kontroli
Definiowanie nazwanych rate limiterów w AppServiceProvider daje precyzyjną kontrolę nad limitami w zależności od kontekstu użytkownika. To podejście jest bardziej elastyczne niż parametry throttle podawane bezpośrednio w trasie.
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);
});
});
}Zastosowanie nazwanych limiterów do tras odbywa się za pomocą składni throttle:nazwa:
Route::middleware('throttle:api')->group(function () {
Route::apiResource('/posts', PostController::class);
});
// routes/web.php
Route::middleware('throttle:login')
->post('/login', [AuthController::class, 'login']);Powyższy warstwowy rate limiter demonstruje wzorzec produkcyjny: użytkownicy enterprise otrzymują wyższe limity, uwierzytelnieni użytkownicy umiarkowane, a anonimowe żądania są ograniczane agresywnie. Metoda by() określa klucz rate limitu — identyfikator użytkownika dla uwierzytelnionych i adres IP jako rozwiązanie awaryjne.
Gotowy na rozmowy o Laravel?
Ćwicz z naszymi interaktywnymi symulatorami, flashcards i testami technicznymi.
Tworzenie własnych middleware od podstaw
Tworzenie własnych middleware obejmuje scenariusze, których wbudowane middleware nie obsługują. Komenda Artisan make:middleware tworzy nową klasę z prawidłową strukturą.
php artisan make:middleware EnsureUserHasRoleMiddleware kontroli dostępu opartej na rolach
Częstym wzorcem własnego middleware jest wymuszanie autoryzacji opartej na rolach na poziomie trasy, przyjmujące nazwy ról jako parametry.
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);
}
}Parametr wariadyczny ...$roles pozwala na przekazywanie wielu ról oddzielonych przecinkami. Rejestracja i użycie wyglądają następująco:
->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 transformacji żądań
Middleware może modyfikować żądanie zanim dotrze do kontrolera. Przykład middleware dla API JSON, które wymusza nagłówki content type i przycina dane wejściowe:
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);
}
}To middleware obsługuje dwa aspekty: waliduje typ zawartości dla żądań POST i sanityzuje wszystkie dane wejściowe typu string, usuwając białe znaki.
Rejestracja middleware w Laravel 12
Laravel 12 centralizuje całą rejestrację middleware w pliku bootstrap/app.php. Zastąpiło to starsze podejście z plikiem app/Http/Kernel.php, które istniało przed Laravel 11.
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();Tablica priority ma znaczenie, gdy wiele middleware jest przypisanych do tej samej trasy. Laravel sortuje je zgodnie z tą listą, zapewniając uruchomienie sesji przed uwierzytelnianiem, a uwierzytelniania przed sprawdzaniem ról.
Middleware uruchamia się w kolejności rejestracji. Dla middleware na poziomie trasy tablica priority nadpisuje domyślną kolejność. Uwierzytelnianie powinno być zawsze umieszczane przed autoryzacją, aby uniknąć sprawdzania ról na nieuwierzytelnionych żądaniach.
Terminable middleware dla zadań po odpowiedzi
Terminable middleware wykonuje logikę po wysłaniu odpowiedzi do klienta. Jest to przydatne do logowania, analityki lub zadań porządkowych, które nie powinny blokować użytkownika.
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(),
]);
}
}Metoda terminate otrzymuje zarówno oryginalne żądanie, jak i ostateczną odpowiedź. Middleware należy zarejestrować jako singleton w AppServiceProvider, aby upewnić się, że ta sama instancja obsługuje zarówno handle(), jak i terminate().
Praktyczne wzorce middleware w produkcji
Kilka wzorców middleware pojawia się konsekwentnie w produkcyjnych aplikacjach Laravel.
Obejście trybu konserwacji — umożliwia dostęp do aplikacji z wewnętrznych adresów IP podczas konserwacji:
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);
}
}Nagłówki bezpieczeństwa — dodaje HSTS, politykę bezpieczeństwa treści i inne nagłówki do każdej odpowiedzi:
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;
}
}Te wzorce demonstrują dwie podstawowe pozycje middleware: przed żądaniem (obejście konserwacji sprawdza IP i potencjalnie blokuje) oraz po odpowiedzi (nagłówki bezpieczeństwa modyfikują wychodzącą odpowiedź).
Gotowy na rozmowy o Laravel?
Ćwicz z naszymi interaktywnymi symulatorami, flashcards i testami technicznymi.
Podsumowanie
- Middleware w Laravel działa jako potok: każda klasa przetwarza żądanie, wykonuje na nim operacje i przekazuje je dalej lub przerywa łańcuch, zwracając odpowiedź
- Middleware
authchroni trasy za pomocą uwierzytelniania opartego na guardach, wspierając wiele typów użytkowników poprzez składnięauth:guard - Rate limiting przez middleware
throttlei nazwane definicjeRateLimiter::for()umożliwia warstwową kontrolę dostępu na podstawie kontekstu użytkownika - Własne middleware obsługują zagadnienia przekrojowe, takie jak sprawdzanie ról, sanityzacja żądań i nagłówki bezpieczeństwa, bez zaśmiecania kontrolerów
- Cała rejestracja middleware w Laravel 12 odbywa się w
bootstrap/app.phpza pomocą płynnego API, z tablicąprioritykontrolującą kolejność wykonywania - Terminable middleware wykonuje zadania po odpowiedzi (analityka, logowanie) bez wpływu na opóźnienie odczuwane przez użytkownika
- Parametry middleware za pomocą składni
:paramutrzymują definicje tras ekspresyjne, a klasy middleware wielokrotnego użytku w różnych kontekstach
Zacznij ćwiczyć!
Sprawdź swoją wiedzę z naszymi symulatorami rozmów i testami technicznymi.
Tagi
Udostępnij
Powiązane artykuły

25 pytań rekrutacyjnych z Laravel i PHP w 2026 roku
25 najczęściej zadawanych pytań rekrutacyjnych z Laravel: Service Container, Eloquent ORM, middleware, kolejki, bezpieczeństwo, testowanie i wzorce architektoniczne z przykładami kodu.

Laravel 11: Budowa kompletnej aplikacji od podstaw
Kompleksowy przewodnik po budowie aplikacji w Laravel 11 z uwierzytelnianiem, REST API, Eloquent ORM i wdrożeniem produkcyjnym. Praktyczny poradnik dla początkujących i średnio zaawansowanych programistów.

Symfony 7: API Platform i Najlepsze Praktyki
Kompletny przewodnik po budowaniu profesjonalnych REST API z Symfony 7 i API Platform 4. State Providers, Processors, walidacja i serializacja z praktycznymi przykładami.