Middleware Laravel - Perwira Learning Center

Latar Belakang

Sebagai lanjutan dari pembahasan mengenai file upload di Laravel, tahap berikutnya adalah mempelajari middleware. Dalam pengembangan aplikasi web, sering kali diperlukan mekanisme untuk memeriksa atau memproses sebuah request sebelum request tersebut sampai ke controller. Middleware berfungsi sebagai lapisan perantara yang dapat digunakan untuk melakukan berbagai pengecekan, seperti autentikasi pengguna, validasi akses, atau pengaturan lainnya.

Artikel ini dibuat dengan tujuan untuk mendokumentasikan hasil pembelajaran saya mengenai penggunaan middleware di Laravel. Dengan memahami konsep ini, saya dapat mengatur alur request dalam aplikasi dengan lebih terkontrol serta memastikan bahwa setiap permintaan diproses sesuai dengan aturan yang telah ditentukan.

Alat dan Bahan

Alat dan Bahan yang digunakan yaitu sebagai berikut:

A. Perangkat Lunak

  • Web browser (Google Chrome) 
  • Code editor (Visual Studio Code)
  • Terminal
  • Web server    
  • Composer 
  • PHP
  • Laravel

B. Perangkat Keras

  • Laptop

Apa Itu Middleware?

Bayangkan Anda sedang memasuki sebuah gedung perkantoran. Sebelum sampai ke ruangan yang Anda tuju, ada beberapa pos pemeriksaan: satpam yang memeriksa identitas, resepsionis yang menanyakan keperluan, dan mungkin pintu putar yang hanya bisa dilewati dengan kartu akses. Dalam dunia Laravel, middleware persis seperti pos-pos pemeriksaan tersebut.

Middleware adalah mekanisme penyaringan HTTP request yang masuk ke aplikasi kita. Ia bertindak sebagai lapisan antara request yang masuk dan aplikasi (controller) yang akan memproses request tersebut. Setiap request harus melewati middleware sebelum akhirnya mencapai tujuan akhirnya.

Kenapa Middleware Penting dalam Backend?

Dalam pengembangan backend, middleware memiliki peran krusial:

  1. Autentikasi dan Otorisasi – Memastikan hanya pengguna yang berhak yang bisa mengakses route tertentu

  2. Logging – Mencatat setiap request yang masuk ke sistem

  3. Modifikasi Request – Menambahkan atau mengubah data request sebelum diproses controller

  4. Rate Limiting – Membatasi jumlah request dari IP tertentu

  5. CORS – Mengelola kebijakan cross-origin resource sharing

Tanpa middleware, kita akan menulis kode yang sama berulang-ulang di setiap controller untuk melakukan tugas-tugas di atas. Middleware memungkinkan kita menerapkan logika tersebut secara terpusat dan reusable.

Request Lifecycle di Laravel

Untuk memahami middleware, kita perlu mengerti bagaimana Laravel memproses request. Mari kita lihat alurnya:

Request Masuk → Global Middleware → Route Middleware → Controller → Response Keluar

Penjelasan Sederhana

  1. Request Masuk
    Pengguna mengakses URL aplikasi kita, misalnya https://toko-online.com/admin/produk.

  2. Global Middleware
    Request melewati middleware yang diterapkan untuk semua route. Contohnya:

    • Pengecekan apakah aplikasi dalam mode maintenance

    • Validasi ukuran request

    • Enkripsi cookie

  3. Route Middleware
    Setelah itu, Laravel menentukan route mana yang cocok dengan URL yang diakses. Jika route tersebut memiliki middleware khusus (misalnya middleware auth atau admin), maka request akan melewatinya.

  4. Controller
    Setelah semua middleware memberikan izin, barulah request sampai ke controller. Controller memproses request, misalnya mengambil data dari database.

  5. Response
    Controller mengembalikan response yang kemudian melewati middleware lagi (dalam urutan terbalik) sebelum dikirim ke browser pengguna.

Yang menarik, middleware bisa menghentikan request lebih awal. Misalnya, jika middleware auth mendeteksi pengguna belum login, ia bisa langsung mengembalikan response redirect ke halaman login, tanpa perlu memanggil controller sama sekali.

Membuat Custom Middleware

Sekarang kita akan praktik membuat custom middleware. Studi kasus kita adalah toko online yang ingin membatasi akses ke halaman manajemen produk hanya untuk pengguna dengan peran (role) admin.

Perintah Artisan untuk Membuat Middleware

Laravel menyediakan perintah Artisan untuk membuat middleware dengan mudah. Buka terminal dan jalankan:

php artisan make:middleware AdminMiddleware

Perintah ini akan membuat file baru di app/Http/Middleware/AdminMiddleware.php.

Struktur File Middleware

Mari kita lihat struktur dasar middleware yang baru dibuat:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class AdminMiddleware
{
    public function handle(Request $request, Closure $next)
    {
        // Logika middleware kita akan ditulis di sini
        return $next($request);
    }
}

Method handle()

Method handle() adalah jantung dari middleware. Di sinilah kita menulis logika penyaringan. Method ini menerima dua parameter:

  • $request: Objek request yang masuk

  • $next: Closure yang akan memanggil middleware berikutnya atau controller

Yang perlu dipahami: middleware bisa melakukan tiga hal:

  1. Mengizinkan request lanjut dengan memanggil return $next($request)

  2. Menghentikan request dengan me-return response sendiri, misalnya redirect atau error

  3. Memodifikasi request dengan mengubah data sebelum memanggil $next($request)

Sekarang mari kita implementasikan logika untuk middleware admin kita:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class AdminMiddleware
{
    public function handle(Request $request, Closure $next)
    {
        // Cek apakah user sudah login
        if (!Auth::check()) {
            return redirect()->route('login')->with('error', 'Silakan login terlebih dahulu');
        }

        // Cek apakah user yang login memiliki role admin
        if (Auth::user()->role !== 'admin') {
            abort(403, 'Unauthorized. Halaman ini hanya untuk admin.');
        }

        // Jika user adalah admin, lanjutkan request
        return $next($request);
    }
}

Dalam kode di atas, kita melakukan dua pengecekan:

  • Pertama, pastikan user sudah login. Jika belum, redirect ke halaman login.

  • Kedua, pastikan user memiliki role 'admin'. Jika tidak, tampilkan error 403 (Forbidden).

Mendaftarkan Middleware

Setelah membuat middleware, kita harus mendaftarkannya di Laravel agar bisa digunakan. Pendaftaran dilakukan di file app/Http/Kernel.php.

Register di Kernel

Di dalam file Kernel.php, ada dua tempat utama untuk mendaftarkan middleware:

protected $routeMiddleware = [
    // middleware bawaan Laravel
    'auth' => \App\Http\Middleware\Authenticate::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,

    // daftarkan middleware kita di sini
    'admin' => \App\Http\Middleware\AdminMiddleware::class,
];

Perbedaan Global Middleware dan Route Middleware

Di Kernel.php, ada beberapa properti yang perlu dipahami:

  1. $middleware (Global Middleware)

    • Middleware di sini akan dijalankan untuk SEMUA request ke aplikasi

    • Cocok untuk tugas seperti CORS, maintenance mode, atau trimming string

    • Contoh: \App\Http\Middleware\TrustProxies::class

  2. $middlewareGroups (Middleware Groups)

    • Mengelompokkan beberapa middleware dengan nama tertentu

    • Laravel punya group web (untuk route dengan session) dan api (untuk route API)

    • Contoh: middleware web berisi middleware untuk menangani cookie, session, dll.

  3. $routeMiddleware (Route Middleware)

    • Middleware yang bisa ditetapkan secara spesifik ke route tertentu

    • Kita bisa memberikan alias seperti 'admin' untuk middleware kita

    • Middleware ini hanya berjalan jika route yang diakses menggunakannya

Melindungi Route Tertentu

Setelah mendaftarkan middleware, kita bisa menggunakannya untuk melindungi route tertentu.

Penggunaan Middleware pada Route

Ada beberapa cara menerapkan middleware ke route:

Cara 1: Langsung di file routes/web.php

// Single route dengan middleware
Route::get('/admin/produk', [ProdukController::class, 'index'])->middleware('admin');

// Route group dengan middleware
Route::middleware(['admin'])->group(function () {
    Route::get('/admin/produk', [ProdukController::class, 'index']);
    Route::get('/admin/produk/create', [ProdukController::class, 'create']);
    Route::post('/admin/produk', [ProdukController::class, 'store']);
});

Cara 2: Di controller (jika menggunakan resource controller)

public function __construct()
{
    $this->middleware('admin')->except(['index', 'show']);
}

Contoh Proteksi Endpoint

Mari kita lihat contoh lengkap proteksi endpoint untuk manajemen produk:

// routes/web.php
Route::get('/', [HomeController::class, 'index'])->name('home');

// Route publik - bisa diakses siapa saja
Route::get('/produk', [ProdukController::class, 'index'])->name('produk.index');
Route::get('/produk/{id}', [ProdukController::class, 'show'])->name('produk.show');

// Route yang dilindungi - hanya admin
Route::middleware(['admin'])->group(function () {
    Route::get('/admin/dashboard', [DashboardController::class, 'index'])->name('admin.dashboard');
    Route::resource('/admin/produk', AdminProdukController::class);
    Route::get('/admin/laporan', [LaporanController::class, 'index'])->name('admin.laporan');
});

Dengan pengaturan di atas:

  • Pengguna biasa bisa melihat daftar produk dan detail produk

  • Hanya admin yang bisa mengakses dashboard admin dan melakukan operasi CRUD produk

Jika pengguna biasa mencoba mengakses /admin/produk, mereka akan mendapatkan error 403 Forbidden seperti yang kita atur di middleware.

Contoh Studi Kasus

Mari kita buat studi kasus yang lebih kompleks untuk toko online. Misalkan kita punya beberapa tingkatan user:

  • Admin: Bisa melakukan semua operasi

  • Seller (Penjual): Bisa mengelola produknya sendiri

  • Customer: Hanya bisa melihat dan membeli

Kita akan buat middleware untuk memastikan seller hanya bisa mengakses produk miliknya.

Middleware: SellerMiddleware

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class SellerMiddleware
{
    public function handle(Request $request, Closure $next)
    {
        // Pastikan user login
        if (!Auth::check()) {
            return redirect()->route('login');
        }

        $user = Auth::user();

        // Admin bisa mengakses semua
        if ($user->role === 'admin') {
            return $next($request);
        }

        // Seller hanya bisa akses jika role-nya seller
        if ($user->role !== 'seller') {
            abort(403, 'Halaman ini khusus untuk penjual');
        }

        // Jika route memiliki parameter produk (misal route model binding)
        // Kita cek apakah produk ini milik seller tersebut
        if ($request->route('produk')) {
            $produk = $request->route('produk');

            if ($produk->user_id !== $user->id) {
                abort(403, 'Anda tidak memiliki akses ke produk ini');
            }
        }

        return $next($request);
    }
}

Pendaftaran di Kernel

// app/Http/Kernel.php
protected $routeMiddleware = [
    // ... middleware lainnya
    'admin' => \App\Http\Middleware\AdminMiddleware::class,
    'seller' => \App\Http\Middleware\SellerMiddleware::class,
];

Penggunaan di Route

// routes/web.php
Route::middleware(['auth'])->group(function () {

    // Route untuk customer
    Route::get('/keranjang', [CartController::class, 'index'])->name('cart.index');
    Route::post('/checkout', [OrderController::class, 'store'])->name('checkout');

    // Route untuk seller
    Route::middleware(['seller'])->prefix('seller')->name('seller.')->group(function () {
        Route::get('/produk', [SellerProdukController::class, 'index'])->name('produk.index');
        Route::get('/produk/create', [SellerProdukController::class, 'create'])->name('produk.create');
        Route::post('/produk', [SellerProdukController::class, 'store'])->name('produk.store');
        Route::get('/produk/{produk}/edit', [SellerProdukController::class, 'edit'])->name('produk.edit');
        Route::put('/produk/{produk}', [SellerProdukController::class, 'update'])->name('produk.update');
        Route::delete('/produk/{produk}', [SellerProdukController::class, 'destroy'])->name('produk.destroy');
    });

    // Route untuk admin
    Route::middleware(['admin'])->prefix('admin')->name('admin.')->group(function () {
        Route::resource('users', UserController::class);
        Route::get('/laporan/penjualan', [LaporanController::class, 'penjualan'])->name('laporan.penjualan');
    });
});

Contoh Controller dengan Middleware

<?php

namespace App\Http\Controllers\Seller;

use App\Http\Controllers\Controller;
use App\Models\Produk;
use Illuminate\Http\Request;

class SellerProdukController extends Controller
{
    public function edit(Produk $produk)
    {
        // Middleware sudah memastikan produk ini milik seller yang sedang login
        // Jadi kita bisa langsung menampilkan form edit
        return view('seller.produk.edit', compact('produk'));
    }

    public function update(Request $request, Produk $produk)
    {
        // Aman karena middleware sudah memverifikasi kepemilikan
        $produk->update($request->all());

        return redirect()->route('seller.produk.index')
            ->with('success', 'Produk berhasil diupdate');
    }
}

Dengan implementasi di atas, kita punya sistem otorisasi yang rapi:

  • Admin bisa mengakses semua fitur, termasuk manajemen user

  • Seller hanya bisa mengelola produknya sendiri

  • Customer tidak bisa mengakses halaman manajemen sama sekali

Hasil Pembelajaran

Melalui pembelajaran ini, saya memahami bahwa middleware bekerja sebagai perantara antara request yang masuk dan controller yang akan memprosesnya. Middleware dapat digunakan untuk melakukan berbagai pengecekan, seperti memastikan pengguna telah melakukan login sebelum mengakses halaman tertentu.

Saya juga mempelajari bahwa Laravel telah menyediakan beberapa middleware bawaan, serta memungkinkan developer untuk membuat middleware sendiri sesuai kebutuhan aplikasi. Middleware kemudian dapat didaftarkan pada route tertentu atau pada kelompok route agar aturan yang sama dapat diterapkan secara konsisten.

Kesimpulan

Middleware merupakan komponen penting dalam Laravel yang berfungsi untuk mengatur dan mengontrol alur request sebelum diproses oleh controller. Dengan adanya middleware, berbagai proses pengecekan dapat dilakukan secara terpusat tanpa harus menuliskannya berulang kali di dalam controller.

Pemahaman mengenai middleware membantu dalam membangun aplikasi yang lebih terstruktur, aman, dan mudah dikelola karena logika pengecekan dapat dipisahkan dari logika utama aplikasi.