Middleware, Manfaat dan Penggunaannya

Dalam melakukan pengembangan aplikasi berbasis web, seringkali kita berkeinginan untuk memfilter setiap request yang masuk kedalam aplikasi kita. Hal ini dilakukan dengan tujuan untuk melakukan proses verifikasi terhadap setiap request yang masuk seperti misalnya melakukan pengecekan status login, privillage, atau bahkan melakukan pengecekan token CSRF (Cross-Site Request Forgery) untuk memastikan bahwa request yang masuk berasal dari komputer yang valid. Dengan menggunakan framework Laravel, kita dapat mengimplementasikan mekanisme tersebut dengan bantuan fitur Middleware yang telah disediakan oleh laravel-5 (pada laravel-4 fitur ini disebut sebagai filter dengan konsep yang sedikit berbeda).

So, apa sih Middleware itu? sebenarnya dalam dunia IT istilah middleware biasa digunakan untuk menyebut sebuah perangkat lunak yang berperan sebagai “penengah” antara sebuah aplikasi dengan aplikasi lain untuk mempermudah proses integrasi antara aplikasi-aplikasi tersebut. Dalam konteks Laravel, Middleware merupakan sebuah Class khusus yang berperan sebagai “penengah” antara request yang masuk dengan Controller yang dituju. Secara umum, prinsip kerja Middleware adalah mencegat request yang masuk untuk kemudian diproses terlebih dahulu sebelum diberikan kepada Controller yang dituju atau diarahkan ke Controller yang lain. Dengan menggunakan fitur ini, kita dapat membuat komponen yang reusable untuk melakukan pekerjaan-pekerjaan tersebut.

Cara Mendefinisikan Middleware

Ok, sekarang bagaimana sih cara mengggunakananya? Secara default Laravel telah menyediakan tiga buah Middleware dengan nama Authenticate.php, RedirectIfAuthenticated.php dan VerifyCsrfToken.php yang berlokasi di direktori app/Http/Middleware. Untuk dapat menambahkan Middleware baru kita cukup membuat kelas baru dengan format berikut ini:

<?php

namespace App\Http\Middleware;

use Closure;

class MyMiddleware
{
    public function handle($request, Closure $next)
    {
        //letakkan kode kamu disini...
    }
}

Seperti yang terlihat pada kode diatas, dalam setiap Middleware terdapat sebuah method khusus yang bernama handle(). Method tersebut memiliki dua buah parameter yaitu Illuminate\Http\Request $request dan Closure $next. Method ini akan dipanggil secara otomatis oleh Laravel ketika kita meregistrasikan middleware tersebut. Lalu, kode seperti apakah yang harus kita letakkan di dalam method handle() tersebut. Berikut ini adalah contoh bagaimana membuat mendefinisikan method handle() yang digunnakan untuk memfilter setiap request agar alamat yang dituju hanya dapat diakses oleh user dengan role admin.

public function handle($request, Closure $next)
{
    $user = Auth::user();
    if($user->role === User::ROLE_ADMIN) {
        return $next($request);
    }

    return redirect('home');
}

Contoh kode di atas merupakan kode sederhana yang melakukan pengecekan terhadap role dari user yang sedang login pada saat itu. Apabila user yang sedang login memiliki role admin, maka kita akan meneruskan request yang masuk dan memberikannya kepada Controller yang dituju (dengan memanggil method $next($request)). Namun, apabila user yang melakukan request tidak memiliki role sebagai adminmaka kita akan me-_redirect user_ tersebut ke halaman home. Dengan cara ini kita dapat mem-filter setiap request yang masuk dengan mudah.

Before/After Middleware

Secara umum, Middleware pada laravel dapat digolongkan kedalam dua kelompok yaitu After Middleware dan Before Middleware. After Middleware merupakan Middleware yang diproses setelah request masuk kedalam Controller, sedangkan Before Middlware merupakan Middleware yang diproses sebelum request masuk kedalam Controller. Berikut ini adalah contoh mendefinisikan kedua buah Middlware tersebut.

<?php

namespace App\Http\Middleware;

use Closure;

class BeforeMiddleware
{
    public function handle($request, Closure $next)
    {
        //lakukan sesuatu terhadap request yang masuk..

        return $next($request)
    }
}

Contoh kode di atas merupakan contoh bagaimana mendefinisikan sebuah Before Middleware pada Laravel. Pada kode tersebut terlihat bahwa request yang masuk akan diproses terlebih dahulu sebelum diteruskan ke Controller yang dituju.

<?php

namespace App\Http\Middleware;

use Closure;

class AfterMiddleware
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        //lakukan sesuatu terhadap response yang diperoleh

        return $response
    }
}

Berbeda dengan ‘Before Middleware’, pada After Middleware kita meneruskan request yang masuk ke Controller yang dituju terlebih dahulu hingga mendapatkan response dari Controller tersebut. Setelah mendapatkan response yang dimaksud, kita akan memprosesnya lebih lanjut sebelum nantinya dikembalikan ke web browser untuk kemudian di render.

Meregistrasikan Middlware Secara Global

Setiap Middleware yang dibuat dapat diregistrasikan secara global sehingga Middleware terssebut akan selalu dipanggil setiap ada request yang masuk. untuk dapat meregistrasikan Middleware yang dibuat secara global, kita dapat menambahkannya di dalam file app/Http/Kernel.php seperti contoh di bawah ini:

protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    \App\Http\Middleware\EncryptCookies::class,
    \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,

    \App\Http\Middleware\MyGlobalMiddleware::class, //Middlware yang baru dibuat
];

Meregistrasikan Middlware Pada Routes

Selain dapat didefinisikan secara global, komponen Middleware yang dibuat juga dapat diregistrasikan secara spesifik untuk digunakan pada Routes tertentu dengan cara menambahkan nama Middleware yang dibuat kedalam file app/Http/Kernel.php seperti contoh dibawah ini:

protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'csrf' => \App\Http\Middleware\VerifyCsrfToken::class,
    'oauth' => \LucaDegasperi\OAuth2Server\Middleware\OAuthMiddleware::class,
    'oauth-owner' => \LucaDegasperi\OAuth2Server\Middleware\OAuthOwnerMiddleware::class,
    'my-middlware' => \App\Http\Middleware\MyGlobalMiddleware::class, //Middlware yang baru dibuat
];

Setelah meregistrasikan Middleware kita kedalam $routeMiddleware seperti contoh diatas, berikutnya adalah memberitahu Laravel Routes mana saja yang akan menggunakan Middleware tersebut dengan cara menambahkan key middlware pada bagian route options yang berada di file app/Http/routes.php seperti contoh dibawah ini:

Route::get('admin', [
    'uses' => [email protected]',
    'middleware' => 'my-middleware'
]);

Meregistrasikan Middleware Pada Controller

Selain dapat diregistrasikan secara global dan disematkan pada Routes, Middleware juga dapat diregistrasikan secara spesifik pada Controller. Dengan meregistrasikan Middleware yang dibuat kedalam Controller, Middleware tersebut akan berlaku untuk setiap method yang ada di dalam Controller tersebut. Lalu, apa bedanya ketika kita mendefinisikan Middleware pada Routes dengan mendefinisikannya pada Controller? Perbedaannya adalah, ketika kita mendefinisikan Middleware pada Controller, kita dapat memberikan opsi kepada Middleware tersebut agar hanya dieksekusi pada method tertentu saja ataupun meng-_exclude_ beberapa method yang tidak ingin disematkan Middleware. Berikut ini adalah contoh bagaimana mendefinisikan Middleware pada Controller:

class MyController extends Controller
{
    function __construct()
    {
        $this->middleware('my-middleware');
        $this->middleware('log-middleware', ['only' => ['foo', 'bar']]); //selected method
        $this->middleware('subscribe-middleware', ['except' => ['baz']]) ; //exclude method
    }
}  

Lebih Lanjut Tentang Middleware

Penjelasan diatas hanya mencakup dasar-dasar dan penggunaan secara umum dari Middlware Laravel-5. Untuk penjelasan lebih lanjut terkait dengan Middleware seperti misalnya pemanfaatan method terminate() dan penggunaan parameter pada Middleware, saya merekomendasikan rekan-rekan sekalian untuk langsung membaca dokumentasi tentang Middleware disini. Sekian yang bisa saya sampaikan pada kesempatan kali ini semoga artikel ini dapat bermanfaat untuk rekan-rekan sekalian. Selamat belajar dan bereksperimen :).