Laravel Middleware Cara Membuat Dan Menggunakan

kalau kalian pernah lihat kode route Laravel yang ada ->middleware('auth') dan bingung dari mana datangnya, di artikel ini saya bongkar tuntas konsep middleware dari nol sampai bisa bikin sendiri. middleware adalah konsep yang paling sering saya pakai untuk menjaga keamanan aplikasi, memeriksa siapa yang boleh mengakses halaman apa sebelum request sampai ke controller.
posisinya di antara request dan response, persis seperti satpam yang berdiri di pintu: boleh lanjut atau disuruh balik. kita akan bahas cara membuatnya, mendaftarkannya di Laravel 11 ke atas maupun versi lama, memakai parameter, sampai studi kasus filter role admin.
Apa Itu Middleware di Laravel?
di Laravel, setiap request yang masuk tidak langsung lompat ke controller. request melewati barisan middleware dulu, satu per satu, baru deh sampai ke logika aplikasi kalian. alurnya sederhana:
Request -> Middleware 1 -> Middleware 2 -> ... -> Controller -> Response
setiap middleware cuma punya satu tugas utama: menerima request, memeriksa kondisi tertentu, lalu memutuskan diteruskan atau tidak. kalau kondisi tidak terpenuhi, middleware bisa menghentikan request dengan mengembalikan response sendiri, misalnya redirect atau abort(403).
contoh paling gampang dipahami adalah middleware auth. saat kalian akses /dashboard yang dipasangi auth, Laravel mengecek apakah user sudah login:
- sudah login? lanjut ke controller, halaman tampil
- belum login? request dihentikan, user dilempar ke halaman login
tanpa middleware, kalian harus menulis cek if (!auth()->check()) redirect('/login') di setiap controller, duplikasi kode di mana-mana. middleware memusatkan pengecekan itu di satu tempat.
Middleware Bawaan Laravel
sebelum bikin sendiri, kenalan dulu sama yang sudah disediakan Laravel karena kemungkinan besar kebutuhan kalian sudah tercakup:
| Middleware | Kegunaan |
|---|---|
auth | Wajib login, kalau belum diarahkan ke halaman login |
guest | Khusus tamu yang belum login, contoh halaman register |
auth.basic | Autentikasi HTTP basic, biasanya untuk API internal |
verified | Wajib verifikasi email dulu sebelum akses |
signed | Validasi tanda tangan URL, untuk link sekali pakai |
throttle | Batasi jumlah request per menit, anti brute force |
csrf | Proteksi Cross-Site Request Forgery, sudah aktif global di grup web |
pemakaiannya tinggal tempel di route:
Route::get('/dashboard', [DashboardController::class, 'index'])
->middleware('auth', 'verified');
sekali paham pola ini, bikin middleware custom tinggal mengikuti pola yang sama.
Membuat Custom Middleware
untuk studi kasus kita bikin middleware CheckRole yang membatasi akses berdasarkan role user, misal halaman admin cuma boleh dibuka role admin. buat dulu file-nya dengan artisan:
php artisan make:middleware CheckRole
perintah itu membuat file baru di app/Http/Middleware/CheckRole.php. kalau kita buka, isinya template seperti ini:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class CheckRole
{
/**
* Handle an incoming request.
*/
public function handle(Request $request, Closure $next, string $role): Response
{
if (!auth()->check()) {
return redirect('login');
}
if (auth()->user()->role !== $role) {
abort(403, 'Kamu tidak punya akses');
}
return $next($request);
}
}
Anatomi method handle
ini bagian paling penting untuk dipahami, mari kita bedah:
Request $requestberisi semua data request yang masuk: URL, method, header, input form, dan lain-lainClosure $nextadalah pintu gerbang ke lapisan berikutnya, dipanggil saat kita mempersilakan request lanjutreturn $next($request)meneruskan request ke middleware berikutnya atau ke controller- parameter setelah
$next, dalam contohstring $role, adalah parameter tambahan yang dikirim dari route
kalau kondisi gagal, kita tidak memanggil $next, melainkan mengembalikan response sendiri. di situlah letak kekuatan middleware: request bisa dihentikan di tengah jalan tanpa menyentuh controller sama sekali.
di contoh di atas ada dua penjagaan: user yang belum login dilempar ke halaman login, user yang login tapi role-nya beda diberi 403. dua-duanya terjadi sebelum controller dijalankan.
Mendaftarkan Middleware (Laravel 11 ke Atas)
ini bagian yang berubah besar antara versi lama dan baru. sejak Laravel 11, file app/Http/Kernel.php sudah dihapus, pendaftaran middleware pindah ke bootstrap/app.php. kalian wajib mendaftarkan middleware custom di sana supaya bisa dipakai, caranya:
// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'role' => CheckRole::class,
]);
})
alias di sini memberi nama pendek role untuk class CheckRole. setelah terdaftar, barulah role bisa dipakai di route dan controller. jangan lupa import class-nya di bagian atas file:
use App\Http\Middleware\CheckRole;
kalau import-nya lupa, akan muncul error class tidak ditemukan saat aplikasi dijalankan.
Versi lama: Laravel 10 ke bawah
banyak tutorial di luar sana masih memakai cara lama, jadi saya sertakan biar kalian tidak bingung kalau jumpa project versi lama. di Laravel 10 ke bawah, pendaftaran dilakukan di app/Http/Kernel.php pada properti $routeMiddleware:
// app/Http/Kernel.php (Laravel 10 ke bawah)
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'role' => \App\Http\Middleware\CheckRole::class,
];
kesimpulannya: versi 11+ pakai bootstrap/app.php dengan alias, versi 10- pakai Kernel.php. kalau kalian ikut tutorial dan file yang disebut tidak ada, kemungkinan besar versi Laravel-nya tidak sama.
Memakai Middleware di Route
setelah terdaftar, ada tiga cara pemakaian yang umum.
1. Langsung di satu route
Route::get('/admin', [AdminController::class, 'index'])
->middleware('role:admin');
tanda titik dua setelah nama middleware adalah cara mengirim parameter, jadi role:admin artinya middleware role dengan parameter admin. nanti parameter itu diterima di method handle sebagai $role.
2. Grup untuk banyak route
kalau ada beberapa halaman yang butuh proteksi sama, bungkus jadi grup supaya tidak menulis berulang:
Route::middleware('auth')->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
Route::get('/profil', [ProfilController::class, 'index']);
Route::get('/pengaturan', [PengaturanController::class, 'index']);
});
ketiga route di atas otomatis wajib login tanpa perlu menulis middleware('auth') satu per satu.
3. Di dalam controller
kadang lebih rapi memasang dari sisi controller lewat constructor:
class UserController extends Controller
{
public function __construct()
{
$this->middleware('auth');
$this->middleware('role:admin')->only('create');
}
}
di contoh ini semua method dalam UserController wajib login, tapi role:admin hanya berlaku di method create. ada juga kebalikannya except('index') untuk mengecualikan method tertentu.
Middleware Groups: web dan api
Laravel sejak awal mengelompokkan middleware menjadi beberapa grup supaya tidak menulis deretan panjang di tiap route. dua grup utama bawaan:
webuntuk route di fileroutes/web.php, berisi middleware session, cookie encryption, CSRF, dan validationapiuntuk route di fileroutes/api.php, berisi throttling dan API middleware tanpa session
route yang ditulis di web.php otomatis sudah masuk grup web, begitu juga api.php masuk grup api. jadi kalian tidak perlu mikirin CSRF misalnya, itu sudah aktif di semua route web.
kalau mau menambah middleware custom ke grup yang sudah ada, tinggal prepend atau append:
// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
$middleware->web(append: [
LogUserActivity::class,
]);
})
dengan ini LogUserActivity jalan di semua route web, cocok untuk kebutuhan seperti pencatatan aktivitas global.
Studi Kasus: Filter Role Admin
sekarang rangkai semuanya jadi satu studi kasus nyata. kita punya tiga role: admin, editor, dan user. halaman kelola artikel hanya boleh diakses admin dan editor. daripada bikin middleware untuk tiap role, kita pakai parameter agar satu middleware bisa menangani banyak role:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class CheckRole
{
public function handle(Request $request, Closure $next, ...$roles): Response
{
if (!auth()->check()) {
return redirect('login');
}
if (!in_array(auth()->user()->role, $roles)) {
abort(403, 'Kamu tidak punya akses ke halaman ini');
}
return $next($request);
}
}
perhatikan ...$roles, ini variadic parameter yang menangkap semua argumen jadi array. jadi kita bisa kirim lebih dari satu role:
Route::middleware('role:admin,editor')->group(function () {
Route::get('/artikel/kelola', [ArtikelController::class, 'kelola']);
Route::get('/artikel/tulis', [ArtikelController::class, 'tulis']);
});
user dengan role admin atau editor lolos, sisanya kena 403. kalau cuma satu role, tulis role:admin saja.
untuk penerapan multi role yang lebih dalam dengan JWT di REST API, saya sudah tuliskan lengkap di artikel membuat multiple role user dengan middleware route laravel, silakan lanjut ke sana kalau project kalian memakai autentikasi token.
Terminable Middleware
ada jenis middleware spesial yang berjalan setelah response dikirim ke browser. ini berguna misalnya untuk mencatat log di akhir request tanpa memperlambat pengiriman response:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class LogRequest
{
public function handle(Request $request, Closure $next): Response
{
return $next($request);
}
public function terminate(Request $request, Response $response): void
{
// catat log setelah response terkirim
logger()->info('Request selesai', [
'url' => $request->fullUrl(),
'status' => $response->getStatusCode(),
]);
}
}
terminate otomatis dipanggil Laravel setelah response terkirim, selama web server memakai FastCGI. untuk keperluan umum seperti cek auth dan role, terminate tidak dibutuhkan, tapi ada baiknya kalian tahu bahwa opsi ini tersedia.
Masalah yang Sering Muncul
beberapa kendala klasik yang saya temui sendiri maupun sering ditanyakan:
Target class [role] does not exist→ alias belum didaftarkan dibootstrap/app.php, atau lupa import class middleware-nya- Middleware jalan di semua route padahal cuma dipasang di satu tempat → kemungkinan middleware tercatat global atau di grup
web, bukan sebagai alias. cek kembali cara pendaftarannya - Request diteruskan padahal kondisi gagal → lupa menambahkan
returnsebelumredirectatauabort, sehingga setelah pengalihan kode tetap lanjut memanggil$next - Parameter middleware tidak terbaca → pastikan urutan parameter di method
handlebenar,$nextharus di posisi kedua sebelum parameter tambahan
Kesimpulan
middleware adalah lapisan filter yang menjaga aplikasi dengan memeriksa request sebelum masuk controller, dan middleware custom dibangun dengan tiga langkah: bikin class lewat php artisan make:middleware, tulis logika di method handle dengan pola return $next($request), lalu daftarkan alias di bootstrap/app.php untuk Laravel 11 ke atas atau Kernel.php untuk versi lama.
setelah terdaftar, middleware bisa dipasang di satu route, di grup, atau lewat constructor controller, bahkan menerima parameter seperti role:admin untuk membedakan level akses. middleware bawaan seperti auth, guest, throttle, dan csrf sudah mencakup kebutuhan umum, jadi jangan buru-buru bikin sendiri sebelum mengecek yang sudah ada.
Baca Juga Mengenai :
Pertanyaan yang Sering Diajukan
Apa itu middleware di Laravel?
Middleware adalah lapisan filter yang memeriksa request HTTP sebelum masuk ke controller dan sebelum response dikirim balik ke user. Contohnya middleware auth yang mengecek apakah user sudah login, kalau belum maka diarahkan ke halaman login, kalau sudah maka request diteruskan.
Di mana mendaftarkan middleware di Laravel 11?
Di file bootstrap/app.php lewat method withMiddleware. Contoh: ->withMiddleware(function (Middleware $middleware) { $middleware->alias([...]) }). Ini menggantikan Kernel.php yang dipakai Laravel 10 ke bawah, file Kernel sudah tidak ada lagi di Laravel 11 ke atas.
Apa bedanya middleware global, grup, dan alias?
Global middleware jalan untuk semua request di aplikasi, middleware grup dipakai di beberapa route sekaligus lewat nama grup seperti web dan api, sedangkan alias adalah nama pendek untuk middleware custom yang dipakai di route atau controller tertentu saja.
Bagaimana cara meneruskan parameter ke middleware?
Tambahkan parameter setelah method handle(Request $request, Closure $next, $param) lalu tulis di route dengan tanda titik dua: Route::get(...)->middleware("role:admin"). Parameter ini dipakai misalnya untuk menentukan role apa saja yang boleh mengakses.
Kenapa muncul error Class middleware does not exist?
Karena middleware custom belum didaftarkan alias-nya di bootstrap/app.php, atau di Laravel 10 ke bawah belum masuk daftar $routeMiddleware di app/Http/Kernel.php. Sertakan juga namespace class yang benar, misal use App\\Http\\Middleware\\CheckRole.
Apa saja middleware bawaan Laravel?
Yang paling sering dipakai: auth, guest, auth.basic, verified, signed, throttle, dan csrf. Semuanya bisa langsung dipakai di route tanpa perlu bikin sendiri, contoh ->middleware("auth") untuk mewajibkan login.

