Laravel Middleware Deep Dive: Authentication, Rate Limiting, dan Custom Middleware
Panduan mendalam tentang Laravel middleware mencakup authentication guard, rate limiting dengan throttle, pembuatan custom middleware, PHP attribute di Laravel 13, dan pola lanjutan untuk aplikasi production.

Laravel middleware berperan sebagai lapisan penyaring antara request HTTP yang masuk dan logika aplikasi. Setiap request melewati rangkaian middleware sebelum mencapai controller, dan setiap response kembali melalui rangkaian yang sama. Pemahaman menyeluruh terhadap mekanisme ini sangat penting bagi pengembang yang ingin membangun aplikasi Laravel yang aman dan berperforma tinggi.
Middleware mencegat request HTTP sebelum mencapai route. Laravel mendaftarkan seluruh middleware di bootstrap/app.php menggunakan fluent API. Middleware bawaan menangani authentication, proteksi CSRF, manajemen session, dan rate limiting secara langsung tanpa konfigurasi tambahan.
Cara Kerja Pipeline Middleware di Laravel
HTTP kernel Laravel memproses setiap request melalui tumpukan middleware. Masing-masing middleware menerima request, menjalankan logikanya, lalu meneruskan request ke lapisan berikutnya melalui $next($request) atau menghentikan pipeline dengan mengembalikan response secara langsung.
Arsitektur ini mengikuti pola Chain of Responsibility. Middleware dapat bertindak sebelum request mencapai controller (misalnya pemeriksaan authentication), setelah response dihasilkan (misalnya menambahkan header), atau keduanya sekaligus.
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
}
}Middleware di atas membungkus request: mencatat waktu mulai sebelum pemrosesan dan mencatat durasi setelah response kembali. Pola before/after ini merupakan inti dari cara kerja middleware.
Authentication Middleware: Melindungi Route
Laravel menyediakan middleware alias auth yang dipetakan ke Illuminate\Auth\Middleware\Authenticate. Menerapkannya pada sebuah route memastikan hanya pengguna yang telah terautentikasi yang dapat mengaksesnya. Pengguna yang belum login akan menerima response 401 (API) atau dialihkan ke halaman 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']);
});Multi-Guard Authentication
Aplikasi yang memiliki beberapa tipe pengguna (panel admin, area pelanggan, API) memperoleh manfaat dari authentication berbasis guard. Middleware auth menerima parameter guard untuk menentukan driver authentication yang digunakan.
// 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']);
});Parameter guard setelah tanda titik dua memberitahu Laravel konfigurasi authentication mana yang harus diverifikasi. Pendekatan ini menjaga logika authentication tetap bersih dan terpisah di berbagai bagian aplikasi.
Middleware guest merupakan kebalikan dari auth, hanya mengizinkan pengguna yang belum terautentikasi untuk melewatinya. Menerapkannya pada route login dan registrasi mencegah pengguna yang sudah login mengakses halaman tersebut.
Rate Limiting dengan Throttle Middleware
Rate limiting pada middleware Laravel melindungi route dari penyalahgunaan menggunakan middleware bawaan throttle. Bentuk paling sederhana menerima dua parameter: jumlah maksimum request dan jendela waktu dalam menit.
// 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']);
});Named Rate Limiter untuk Kontrol Lebih Lanjut
Mendefinisikan named rate limiter di AppServiceProvider memberikan kontrol yang lebih detail terhadap pembatasan berdasarkan konteks pengguna. Pendekatan ini jauh lebih fleksibel dibandingkan parameter throttle secara inline. Lihat dokumentasi rate limiting resmi untuk opsi tambahan.
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);
});
});
}Penerapan named limiter pada route menggunakan sintaks 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']);Rate limiter bertingkat di atas menunjukkan pola yang umum digunakan di production: pengguna enterprise mendapatkan batas lebih tinggi, pengguna terautentikasi mendapatkan batas moderat, dan request anonim dibatasi secara agresif. Method by() menentukan kunci rate limit, menggunakan user ID untuk pengguna terautentikasi dan alamat IP sebagai fallback.
Siap menguasai wawancara Laravel Anda?
Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.
Membuat Custom Middleware dari Awal
Pembuatan custom middleware mencakup skenario yang tidak ditangani oleh middleware bawaan. Perintah Artisan make:middleware menghasilkan class baru dengan struktur yang benar.
php artisan make:middleware EnsureUserHasRoleMiddleware untuk Kontrol Akses Berbasis Role
Salah satu pola custom middleware yang paling umum adalah menerapkan otorisasi berbasis role pada tingkat route, dengan menerima nama role sebagai parameter.
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);
}
}Parameter variadic ...$roles memungkinkan pengiriman beberapa role yang dipisahkan koma. Pendaftaran dan penggunaannya adalah sebagai berikut:
->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 untuk Transformasi Request
Middleware juga dapat memodifikasi request sebelum mencapai controller. Berikut contoh middleware JSON API yang memvalidasi header content type dan memangkas input 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);
}
}Middleware ini menangani dua hal sekaligus: memvalidasi content type untuk request POST dan membersihkan seluruh input string dengan memangkas whitespace.
Pendaftaran Middleware di bootstrap/app.php
Laravel memusatkan seluruh pendaftaran middleware di bootstrap/app.php. Pendekatan ini menggantikan cara lama melalui app/Http/Kernel.php yang digunakan sebelum Laravel 11. Fluent API yang sama dapat digunakan di Laravel 12 dan 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();Array priority sangat penting ketika beberapa middleware diterapkan pada route yang sama. Laravel mengurutkannya sesuai daftar ini, memastikan session dimulai sebelum authentication berjalan, dan authentication selesai sebelum pemeriksaan role dilakukan.
Middleware berjalan sesuai urutan pendaftarannya. Untuk middleware tingkat route, array priority menggantikan urutan default. Selalu tempatkan middleware authentication sebelum middleware authorization untuk menghindari pemeriksaan role pada request yang belum terautentikasi.
PHP Attributes untuk Middleware di Laravel 13
Laravel 13 memperkenalkan PHP attribute #[Middleware] untuk mendeklarasikan middleware langsung pada class dan method controller. Pendekatan ini menyimpan konfigurasi middleware bersama dengan kode yang dilindunginya, sehingga aturan otorisasi lebih mudah dibaca dan dipelihara.
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;
}
}#[Middleware('auth')] di tingkat class berlaku untuk semua method. Attribute di tingkat method ditumpuk di atasnya: store() memerlukan auth dan subscribed. Attribute #[Authorize] terintegrasi dengan sistem policy Laravel, memeriksa izin sebelum method dieksekusi.
Pendekatan berbasis attribute ini bersifat opsional. Middleware di file route dan pendaftaran melalui bootstrap/app.php tetap didukung sepenuhnya. Tim yang lebih menyukai definisi route yang eksplisit dapat terus menggunakan fluent API; tim yang menginginkan controller yang self-documenting dapat mengadopsi attribute.
Terminable Middleware untuk Tugas Pasca-Response
Terminable middleware menjalankan logika setelah response dikirimkan kepada klien. Hal ini sangat berguna untuk pencatatan log, analitik, atau tugas pembersihan yang tidak seharusnya menghambat pengguna.
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(),
]);
}
}Method terminate menerima baik request asli maupun response final. Daftarkan middleware ini sebagai singleton di AppServiceProvider untuk memastikan instance yang sama menangani handle() dan terminate().
Pola Middleware Praktis untuk Production
Beberapa pola middleware secara konsisten muncul dalam aplikasi Laravel di lingkungan production.
Bypass maintenance mode mengizinkan IP internal untuk mengakses aplikasi selama masa pemeliharaan:
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);
}
}Security headers menambahkan HSTS, content security policy, dan header keamanan lainnya pada setiap response:
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;
}
}Pola-pola ini menunjukkan dua posisi utama middleware: sebelum request (bypass maintenance memeriksa IP dan berpotensi memblokir) dan setelah response (security headers memodifikasi response yang keluar).
Siap menguasai wawancara Laravel Anda?
Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.
Sumber
- Laravel Middleware Documentation - Referensi resmi untuk pendaftaran middleware, grup, dan parameter
- Laravel 13 Release Notes - Pengumuman attribute
#[Middleware]dan peningkatanPreventRequestForgery - Laravel Rate Limiting Documentation - RateLimiter facade, named limiter, dan konfigurasi throttle middleware
Pola Middleware Laravel untuk Persiapan Interview
- Middleware Laravel beroperasi sebagai pipeline: setiap class memproses request, menjalankan aksinya, lalu meneruskannya atau menghentikan pipeline dengan mengembalikan response
- Middleware
authmelindungi route dengan authentication berbasis guard, mendukung beberapa tipe pengguna melalui sintaksauth:guard - Rate limiting melalui middleware
throttledan definisiRateLimiter::for()memungkinkan kontrol akses bertingkat berdasarkan konteks pengguna - Custom middleware menangani cross-cutting concern seperti pemeriksaan role, sanitasi request, dan security header tanpa mengotori controller
- Seluruh pendaftaran middleware dilakukan di
bootstrap/app.phpmenggunakan fluent API, denganpriorityyang mengontrol urutan eksekusi - Attribute
#[Middleware]di Laravel 13 memungkinkan deklarasi middleware langsung pada controller, menyimpan aturan otorisasi bersama handler - Terminable middleware menjalankan tugas pasca-response (analitik, logging) tanpa memengaruhi latensi yang dirasakan pengguna
- Parameter middleware melalui sintaks
:parammenjaga definisi route tetap ekspresif dan class middleware dapat digunakan kembali di berbagai konteks
Mulai berlatih!
Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.
Bisakah kamu menemukan bug di Laravel?
Satu potongan kode nyata, satu bug tersembunyi, satu percobaan per hari. Tanpa akun untuk mencoba.

Ditulis oleh
Anthony Fillion-MailletPendiri SharpSkill
Developer fullstack selama lebih dari 10 tahun. Ia menjalankan SharpSkill dan bertanggung jawab atas semua yang diterbitkan di sini.
Diperbarui 21 September 2026
Tag
Bagikan
Artikel terkait

Pertanyaan Interview PHP Laravel Developer 2026: Panduan Persiapan Lengkap
Panduan komprehensif untuk mempersiapkan interview PHP Laravel developer tahun 2026. Mencakup pertanyaan teknis Eloquent ORM, Service Container, authentication, queue, dan testing.

Laravel 12 di 2026: Fitur Baru, Starter Kit, dan Pertanyaan Interview
Laravel 12 menghadirkan starter kit yang dirancang ulang dengan React 19, Vue 3, Livewire 4, dan WorkOS AuthKit. Panduan lengkap fitur baru, jalur upgrade, dan pertanyaan interview penting untuk 2026.

Eloquent ORM: pola dan optimasi untuk Laravel
Kuasai Eloquent ORM dengan pola lanjutan dan teknik optimasi. Eager loading, query scope, accessor, mutator dan performa untuk aplikasi Laravel.