TechTopia Casing SSD NVMe NGFF USB 3.1 Type-C Enclosure Eksternal M.2 SATA & NVMe High Speed

Laravel Middleware: Memahami Cara Kerja dan Contoh Penggunaannya

Dalam aplikasi web, tidak semua request boleh langsung diproses oleh controller. Beberapa request perlu diperiksa terlebih dahulu, misalnya apakah pengguna sudah login, apakah pengguna memiliki permission tertentu, atau apakah request memenuhi kondisi yang ditentukan aplikasi.

Laravel menyediakan Middleware untuk menangani kebutuhan tersebut.

Middleware dapat dianggap sebagai lapisan yang berada di antara HTTP request dan aplikasi. Middleware dapat memeriksa atau memodifikasi request sebelum diteruskan ke controller, dan juga dapat memproses response sebelum dikirim kembali kepada pengguna.

Contoh paling umum adalah middleware authentication. Ketika pengguna mengakses halaman yang hanya boleh dibuka oleh pengguna yang sudah login, middleware dapat memeriksa status autentikasi terlebih dahulu.

Artikel ini membahas Laravel Middleware, cara kerjanya dalam request lifecycle, middleware bawaan Laravel, cara membuat custom middleware, penggunaan middleware pada route dan controller, parameter middleware, middleware alias, hingga praktik terbaik penggunaannya.

Apa Itu Laravel Middleware?

Middleware Laravel adalah mekanisme untuk memeriksa dan memproses HTTP request sebelum request tersebut mencapai tujuan akhirnya, seperti controller atau route closure.

Secara sederhana, alurnya dapat digambarkan seperti berikut:

Browser
   ↓
HTTP Request
   ↓
Middleware
   ↓
Controller
   ↓
Response
   ↓
Middleware
   ↓
Browser

Middleware dapat:

  • meneruskan request;
  • menolak request;
  • mengalihkan pengguna;
  • memeriksa authentication;
  • memeriksa authorization;
  • memodifikasi request;
  • memproses response;
  • mencatat aktivitas tertentu.

Mengapa Middleware Dibutuhkan?

Bayangkan aplikasi memiliki 20 route yang semuanya hanya boleh diakses oleh pengguna yang sudah login.

Tanpa middleware, developer mungkin tergoda menulis pemeriksaan login secara manual pada setiap controller:

if (!auth()->check()) {
    return redirect('/login');
}

Jika kode seperti ini tersebar di banyak tempat, aplikasi menjadi sulit dirawat.

Dengan middleware, pemeriksaan tersebut dapat ditempatkan pada satu lapisan yang dapat digunakan kembali.

Route::middleware('auth')->group(function () {
    Route::get('/dashboard', DashboardController::class);
    Route::get('/profile', ProfileController::class);
});

Dengan pendekatan tersebut, controller dapat fokus pada business logic, sedangkan middleware menangani pemeriksaan request yang bersifat umum.

Bagaimana Middleware Bekerja?

Middleware menerima request dan memiliki kesempatan untuk menentukan apakah request boleh diteruskan.

Konsep sederhananya:

Request
   ↓
Middleware
   ↓
Apakah memenuhi syarat?
   ├── Tidak → Response/Redirect
   │
   └── Ya
        ↓
     Controller
        ↓
     Response

Dalam middleware Laravel, request dapat diteruskan dengan memanggil closure $next.

public function handle(Request $request, Closure $next)
{
    return $next($request);
}

Jika $next($request) tidak dipanggil, request tidak diteruskan ke middleware berikutnya atau controller.

Struktur Dasar Middleware Laravel

Middleware aplikasi biasanya berada di:

app/Http/Middleware/

Contoh middleware:

app/Http/Middleware/CheckUserRole.php

Struktur dasarnya dapat terlihat seperti:

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class CheckUserRole
{
    public function handle(Request $request, Closure $next): Response
    {
        return $next($request);
    }
}

Method utama yang dijalankan middleware adalah handle().

Membuat Custom Middleware

Laravel menyediakan Artisan command untuk membuat middleware.

php artisan make:middleware CheckUserRole

Laravel akan membuat file middleware pada:

app/Http/Middleware/CheckUserRole.php

Setelah itu, developer dapat menambahkan logic sesuai kebutuhan aplikasi.

Contoh Middleware untuk Memeriksa Role

Misalnya hanya user dengan role admin yang boleh mengakses halaman tertentu.

Middleware dapat dibuat seperti:

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class CheckUserRole
{
    public function handle(Request $request, Closure $next): Response
    {
        if (!$request->user() || $request->user()->role !== 'admin') {
            abort(403);
        }

        return $next($request);
    }
}

Jika user bukan admin, middleware menghentikan request dan mengembalikan HTTP status 403 Forbidden.

Jika user memenuhi syarat, request diteruskan:

return $next($request);

Menggunakan Middleware pada Route

Setelah middleware tersedia, middleware dapat diterapkan pada route.

use App\Http\Controllers\AdminController;

Route::get('/admin', [AdminController::class, 'index'])
    ->middleware('check.role');

Nama check.role harus merujuk pada alias middleware yang telah didaftarkan pada aplikasi.

Jika menggunakan middleware class secara langsung, Laravel juga menyediakan pendekatan berbasis class pada route:

use App\Http\Middleware\CheckUserRole;

Route::get('/admin', [AdminController::class, 'index'])
    ->middleware(CheckUserRole::class);

Middleware Bawaan Laravel

Laravel menyediakan berbagai middleware yang menangani kebutuhan umum aplikasi.

Salah satu yang paling sering digunakan adalah:

->middleware('auth')

Middleware tersebut digunakan untuk memastikan pengguna telah terautentikasi sebelum mengakses route tertentu.

Contoh:

Route::get('/dashboard', DashboardController::class)
    ->middleware('auth');

Jika pengguna belum login, middleware authentication dapat mengarahkan atau memberikan response sesuai konfigurasi authentication aplikasi.

Middleware Authentication

Middleware auth merupakan salah satu contoh middleware yang sangat umum.

Misalnya:

Route::middleware('auth')->group(function () {
    Route::get('/dashboard', DashboardController::class);
    Route::get('/profile', ProfileController::class);
    Route::get('/settings', SettingsController::class);
});

Dengan group tersebut, seluruh route di dalamnya menggunakan middleware authentication.

Ini lebih rapi dibandingkan menambahkan middleware satu per satu:

Route::get('/dashboard', DashboardController::class)
    ->middleware('auth');

Route::get('/profile', ProfileController::class)
    ->middleware('auth');

Route::get('/settings', SettingsController::class)
    ->middleware('auth');

Middleware Authorization

Authentication dan authorization merupakan dua hal berbeda.

Authentication menjawab:

"Apakah user sudah login?"

Sementara authorization menjawab:

"Apakah user tersebut memiliki izin melakukan tindakan ini?"

Misalnya user sudah login tetapi hanya administrator yang boleh mengakses halaman admin.

Untuk kebutuhan authorization yang lebih kompleks, Laravel menyediakan mekanisme seperti Gates dan Policies. Middleware dapat digunakan bersama mekanisme tersebut untuk mengatur akses route atau area tertentu.

Menggunakan Middleware pada Group Route

Middleware sangat berguna ketika beberapa route memiliki aturan yang sama.

Route::middleware(['auth', 'verified'])->group(function () {
    Route::get('/dashboard', DashboardController::class);
    Route::get('/profile', ProfileController::class);
});

Semua route dalam group tersebut akan melewati middleware:

  • auth;
  • verified.

Jika middleware pertama menghentikan request, middleware berikutnya tidak perlu dijalankan.

Menggunakan Beberapa Middleware

Middleware dapat diberikan dalam bentuk array:

Route::get('/admin', AdminController::class)
    ->middleware(['auth', 'check.role']);

Dengan demikian, request harus melewati middleware yang ditentukan sebelum mencapai controller.

Urutan middleware dapat menjadi penting jika satu middleware bergantung pada hasil middleware sebelumnya.

Middleware dengan Parameter

Middleware tidak harus selalu menggunakan aturan yang sama.

Misalnya middleware role ingin menerima parameter:

Route::get('/admin', AdminController::class)
    ->middleware('role:admin');

Atau:

Route::get('/reports', ReportController::class)
    ->middleware('role:manager');

Middleware dapat menerima parameter setelah parameter utama $next:

public function handle(
    Request $request,
    Closure $next,
    string $role
): Response {
    if (!$request->user() || $request->user()->role !== $role) {
        abort(403);
    }

    return $next($request);
}

Dengan pendekatan tersebut, satu middleware dapat digunakan untuk beberapa role.

Multiple Parameter Middleware

Middleware juga dapat menerima lebih dari satu parameter.

Contoh penggunaan:

Route::get('/reports', ReportController::class)
    ->middleware('role:manager,admin');

Middleware dapat menerima parameter tersebut:

public function handle(
    Request $request,
    Closure $next,
    string ...$roles
): Response {
    $user = $request->user();

    if (!$user || !in_array($user->role, $roles, true)) {
        abort(403);
    }

    return $next($request);
}

Dengan pola tersebut, middleware dapat digunakan untuk beberapa role tanpa membuat middleware terpisah untuk setiap role.

Middleware pada Controller

Middleware juga dapat diterapkan pada controller.

Contoh:

public function __construct()
{
    $this->middleware('auth');
}

Namun, cara penerapan middleware pada controller dapat berbeda tergantung versi Laravel yang digunakan dan struktur controller project Anda.

Jika route sudah menggunakan middleware, tidak perlu menerapkan aturan yang sama kembali pada controller tanpa alasan yang jelas.

Middleware Before dan After

Middleware dapat melakukan pekerjaan sebelum dan sesudah controller dijalankan.

Contoh:

public function handle(Request $request, Closure $next): Response
{
    // Sebelum controller
    logger()->info('Request masuk');

    $response = $next($request);

    // Setelah controller
    logger()->info('Response selesai');

    return $response;
}

Pola tersebut berguna untuk kebutuhan seperti logging, pengukuran waktu request, atau proses tertentu yang perlu dilakukan sebelum dan setelah request diproses.

Mengukur Waktu Eksekusi Request

Middleware dapat digunakan untuk mengukur berapa lama sebuah request diproses.

public function handle(Request $request, Closure $next): Response
{
    $start = microtime(true);

    $response = $next($request);

    $duration = microtime(true) - $start;

    logger()->info('Request duration', [
        'url' => $request->fullUrl(),
        'duration_ms' => round($duration * 1000, 2),
    ]);

    return $response;
}

Informasi tersebut dapat membantu ketika melakukan investigasi terhadap endpoint yang lambat.

Mengakses Data User dari Middleware

Jika authentication middleware sudah berjalan sebelumnya, middleware berikutnya dapat mengakses user melalui request.

$user = $request->user();

Contoh:

public function handle(Request $request, Closure $next): Response
{
    $user = $request->user();

    if (!$user) {
        abort(401);
    }

    return $next($request);
}

Pastikan middleware yang membutuhkan user ditempatkan dalam alur yang memungkinkan informasi authentication tersedia.

Redirect dari Middleware

Middleware dapat mengarahkan pengguna ke halaman lain.

Contohnya:

public function handle(Request $request, Closure $next): Response
{
    if (!$request->user()) {
        return redirect()->route('login');
    }

    return $next($request);
}

Pola ini umum digunakan ketika pengguna harus login sebelum mengakses area tertentu.

Menghentikan Request dengan abort()

Jika request tidak memenuhi syarat, middleware dapat menghentikannya menggunakan abort().

Contoh:

abort(403);

HTTP status 403 berarti server memahami request tetapi menolak memberikan akses.

Untuk resource yang tidak ditemukan, aplikasi dapat menggunakan:

abort(404);

Gunakan status HTTP sesuai dengan kondisi sebenarnya agar response API atau web application tetap semantik.

Mendaftarkan Middleware Alias

Middleware dapat diberi alias agar penggunaannya pada route menjadi lebih singkat.

Contohnya, class:

App\Http\Middleware\CheckUserRole

dapat digunakan pada route dengan alias seperti:

->middleware('role')

Cara pendaftaran middleware dapat berbeda berdasarkan versi Laravel.

Pada struktur Laravel modern, middleware alias dapat dikonfigurasi melalui bootstrap aplikasi, misalnya:

->withMiddleware(function ($middleware) {
    $middleware->alias([
        'role' => \App\Http\Middleware\CheckUserRole::class,
    ]);
})

Untuk project Laravel versi lama, registrasi middleware dapat menggunakan file konfigurasi HTTP kernel. Karena struktur ini berubah antar versi Laravel, selalu sesuaikan dengan versi framework yang digunakan.

Global Middleware

Global middleware adalah middleware yang dijalankan untuk setiap HTTP request yang melewati application HTTP kernel.

Middleware global cocok untuk kebutuhan yang memang harus berlaku secara luas, misalnya:

  • pemrosesan request tertentu;
  • logging global;
  • trusted proxy handling;
  • normalisasi request tertentu.

Jangan menjadikan semua middleware sebagai global middleware. Jika sebuah aturan hanya dibutuhkan pada beberapa route, gunakan route middleware agar lebih spesifik.

Route Middleware

Route middleware hanya diterapkan pada route tertentu.

Contohnya:

Route::get('/admin', AdminController::class)
    ->middleware('auth');

Pendekatan ini biasanya lebih tepat untuk authentication, authorization, role checking, atau aturan lain yang hanya diperlukan oleh area tertentu.

Middleware untuk API

Middleware juga sangat penting dalam aplikasi API.

Contohnya route API yang membutuhkan authentication:

Route::middleware('auth:sanctum')->group(function () {
    Route::get('/profile', function (Request $request) {
        return $request->user();
    });
});

Middleware authentication memastikan request memenuhi mekanisme autentikasi yang digunakan aplikasi sebelum endpoint diproses.

Selain authentication, API dapat menggunakan middleware untuk:

  • rate limiting;
  • authorization;
  • logging;
  • request validation tertentu;
  • menambahkan response header;
  • mengontrol akses berdasarkan kondisi tertentu.

Middleware dan Rate Limiting

Aplikasi API sering membutuhkan pembatasan jumlah request.

Laravel menyediakan mekanisme rate limiting yang dapat digunakan melalui middleware.

Contoh route dengan middleware rate limiting:

Route::middleware('throttle:60,1')->group(function () {
    Route::get('/products', ProductController::class);
});

Angka pada contoh tersebut menentukan batas request sesuai konfigurasi throttle yang digunakan.

Rate limiting sangat berguna untuk endpoint publik yang dapat menerima request dalam jumlah besar.

Middleware dan Request Header

Middleware dapat digunakan untuk menambahkan header pada response.

public function handle(Request $request, Closure $next): Response
{
    $response = $next($request);

    $response->headers->set(
        'X-Application',
        'Laravel'
    );

    return $response;
}

Pola ini dapat digunakan untuk kebutuhan response header tertentu sesuai arsitektur aplikasi.

Urutan Middleware

Ketika sebuah request melewati beberapa middleware, urutannya dapat memengaruhi hasil akhir.

Contohnya:

Request
   ↓
Authentication
   ↓
Authorization
   ↓
Role Check
   ↓
Controller
   ↓
Response

Jika middleware role membutuhkan informasi user, authentication harus sudah memastikan informasi user tersedia sebelumnya.

Karena itu, pahami dependency antar-middleware sebelum menentukan urutan eksekusinya.

Middleware Tidak Sama dengan Controller

Middleware dan controller memiliki tanggung jawab yang berbeda.

KomponenTanggung Jawab
MiddlewareMemfilter dan memproses request/response
ControllerMenangani request dan business flow endpoint
ModelBerinteraksi dengan data dan persistence
Policy/GateMenentukan authorization

Pemisahan tanggung jawab tersebut membantu aplikasi tetap terstruktur.

Kapan Sebaiknya Membuat Custom Middleware?

Custom middleware cocok ketika sebuah aturan:

  • berhubungan dengan HTTP request atau response;
  • digunakan oleh beberapa route;
  • memerlukan filtering sebelum controller;
  • perlu dilakukan secara konsisten pada kelompok endpoint.

Contohnya:

  • memeriksa role;
  • memeriksa subscription;
  • memeriksa status account;
  • menambahkan header;
  • mencatat request;
  • melakukan validasi akses tertentu.

Kapan Tidak Perlu Menggunakan Middleware?

Tidak semua business logic harus dimasukkan ke middleware.

Misalnya perhitungan harga:

$total = $price * $quantity;

Logic seperti ini bukan tanggung jawab middleware.

Demikian juga proses kompleks seperti:

  • menghitung invoice;
  • memproses pembayaran;
  • menghasilkan laporan;
  • memproses business transaction.

Logic tersebut sebaiknya ditempatkan pada service, domain layer, action, atau struktur aplikasi yang sesuai.

Praktik Terbaik Laravel Middleware

Gunakan Middleware untuk Concern yang Bersifat Lintas Route

Jika aturan digunakan pada banyak endpoint, middleware dapat menghindari duplikasi logic.

Jangan Membuat Middleware Terlalu Kompleks

Middleware sebaiknya fokus pada filtering atau processing request/response. Logic bisnis yang kompleks sebaiknya dipindahkan ke komponen yang memang bertanggung jawab terhadap business logic.

Gunakan Status HTTP yang Tepat

Gunakan 401 untuk kondisi authentication yang diperlukan dan 403 ketika user sudah dikenali tetapi tidak memiliki izin melakukan tindakan tertentu, sesuai konteks aplikasi dan mekanisme authentication yang digunakan.

Perhatikan Urutan Middleware

Middleware yang bergantung pada middleware lain harus ditempatkan pada urutan yang sesuai.

Hindari Duplikasi

Jika route group sudah menggunakan middleware tertentu, jangan menambahkan middleware yang sama berulang kali tanpa alasan.

Jangan Memasukkan Secret ke Logging

Jika middleware digunakan untuk logging, jangan mencatat password, token, API key, atau data sensitif lainnya.

Contoh Middleware Lengkap

Berikut contoh middleware untuk memastikan user memiliki role tertentu:

<?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,
        string $role
    ): Response {
        $user = $request->user();

        if (!$user || $user->role !== $role) {
            abort(403);
        }

        return $next($request);
    }
}

Setelah alias middleware dikonfigurasi, middleware dapat digunakan:

Route::middleware(['auth', 'role:admin'])->group(function () {
    Route::get('/admin', AdminController::class);
    Route::get('/admin/users', UserController::class);
});

Alurnya menjadi:

Request
   ↓
auth
   ↓
role:admin
   ↓
Admin Controller
   ↓
Response

Dengan struktur tersebut, authentication dan role checking dipisahkan dari business logic controller.

Kesimpulan

Laravel Middleware merupakan mekanisme penting untuk memfilter dan memproses HTTP request sebelum request mencapai controller, sekaligus memungkinkan pemrosesan response setelah controller selesai.

Middleware sangat cocok digunakan untuk kebutuhan seperti:

  • authentication;
  • authorization;
  • role checking;
  • rate limiting;
  • request logging;
  • response header;
  • filtering request tertentu.

Middleware dasar memiliki pola:

public function handle(Request $request, Closure $next): Response
{
    return $next($request);
}

Custom middleware dapat dibuat menggunakan:

php artisan make:middleware CheckRole

Kemudian diterapkan pada route:

Route::middleware('role:admin')->group(function () {
    Route::get('/admin', AdminController::class);
});

Konsep terpenting adalah memahami bahwa middleware bertugas sebagai lapisan pengaman dan pemroses request/response, bukan sebagai tempat untuk menaruh seluruh business logic aplikasi.

Dengan penggunaan middleware yang tepat, aplikasi Laravel menjadi lebih terstruktur, mengurangi duplikasi kode, dan lebih mudah dikembangkan ketika jumlah route dan kebutuhan akses semakin kompleks.