Table of Contents

Pengenalan

Middleware menyediakan mekanisme untuk memeriksa dan memfilter permintaan HTTP yang masuk ke aplikasi Anda. Misalnya, Laravel menyertakan middleware yang memverifikasi bahwa pengguna aplikasi Anda diautentikasi. Jika pengguna tidak diautentikasi, middleware akan mengarahkan pengguna ke layar login aplikasi Anda. Namun, jika pengguna diautentikasi, middleware akan mengizinkan permintaan untuk melanjutkan lebih jauh ke dalam aplikasi.

Sebagai tambahan Middleware juga dapat dibuat untuk melakukan berbagai tugas selain otentikasi. Misalnya, middleware logging mungkin mencatat semua permintaan yang masuk ke aplikasi Anda. Ada beberapa middleware yang termasuk dalam framework Laravel, termasuk middleware untuk otentikasi dan proteksi CSRF. Semua middleware ini terletak di direktori app/Http/Middleware.

Membuat Middleware
				
					php artisan make:middleware EnsureTokenIsValid
				
			

Perintah ini akan menempatkan kelas EnsureTokenIsValid di dalam direktori app/Http/Middleware Anda. Fungsi middleware ini untuk memastikan akses ke rute diizinkan hanya jika masukan token yang diberikan cocok dengan nilai yang ditentukan. Jika tidak, kami akan mengarahkan pengguna kembali ke Halaman /home:

				
					<?php
 
namespace App\Http\Middleware;
 
use Closure;
 
class EnsureTokenIsValid
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request->input('token') !== 'my-secret-token') {
            return redirect('home');
        }
 
        return $next($request);
    }
}
				
			

Seperti yang Anda lihat, jika token yang diberikan tidak cocok dengan token “my-secret-token”, middleware akan mengembalikan pengalihan HTTP ke klien; jika tidak, permintaan akan diteruskan lebih jauh ke dalam aplikasi. Untuk meneruskan permintaan lebih dalam ke aplikasi (memperbolehkan middleware untuk masuk) anda harus memanggil fungsi $next dan $request.

Bayangkan middleware sebagai rangkaian permintaan HTTP “berlapis” yang harus dilewati sebelum masuk ke aplikasi Anda. Setiap lapisan dapat memeriksa permintaan dan bahkan menolaknya sepenuhnya.

Middleware & Respon(Before After)

Middleware dapat dijalankan sebelum atau setelah meneruskan permintaan untuk masuk ke aplikasi. Misalnya, middleware berikut akan melakukan beberapa tugas sebelum permintaan ditangani oleh aplikasi :

				
					<?php
 
namespace App\Http\Middleware;
 
use Closure;
 
class BeforeMiddleware
{
    public function handle($request, Closure $next)
    {
        // Perform action
 
        return $next($request);
    }
}
				
			

Sementara, middleware berikut akan menjalankan tugasnya setelah permintaan ditangani oleh aplikasi :

				
					<?php
 
namespace App\Http\Middleware;
 
use Closure;
 
class AfterMiddleware
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);
 
        // Perform action
 
        return $response;
    }
}
				
			
Mendaftarkan Middleware
Pendaftaran Global

Jika Anda ingin middleware berjalan di setiap permintaan HTTP ke aplikasi Anda, daftarkan kelas middleware di properti $middleware dari kelas app/Http/Kernel.php Anda.

Pendaftaran ke Route

Jika Anda ingin menetapkan middleware ke route tertentu, pertama-tama Anda harus mendefinisikan kunci middleware di file app/Http/Kernel.php aplikasi Anda. Secara default, properti $routeMiddleware dari kelas ini berisi entri untuk middleware yang disertakan dengan Laravel. Anda dapat menambahkan middleware Anda sendiri ke daftar ini dan menetapkannya sebagai kunci pilihan Anda :

				
					// Within App\Http\Kernel class...
 
protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
				
			

Setelah middleware didefinisikan dalam kernel HTTP baru anda dapat menggunakan metode middleware untuk menetapkannya ke sebuah route:

				
					Route::get('/profile', function () {
    //
})->middleware('auth');
				
			

Anda dapat menetapkan beberapa middleware ke rute dengan menggunakan array nama middleware ke metode middleware :

				
					Route::get('/', function () {
    //
})->middleware(['first', 'second']);
				
			

atau Saat mendaftarkan middleware, Anda juga dapat memanggil nama kelas secara penuh :

				
					use App\Http\Middleware\EnsureTokenIsValid;
 
Route::get('/profile', function () {
    //
})->middleware(EnsureTokenIsValid::class);
				
			
Mengeluarkan Middleware(Pengecualian)

Dalam case ini misal saat anda menetapkan middleware ke suatu grup route, anda mungkin ingin middleware tersebut tidak digunakan oleh beberapa route dalam grup route. Anda dapat melakukannya dengan menggunakan metode withoutMiddleware :

				
					use App\Http\Middleware\EnsureTokenIsValid;
 
Route::middleware([EnsureTokenIsValid::class])->group(function () {
    Route::get('/', function () {
        //
    });
 
    Route::get('/profile', function () {
        //
    })->withoutMiddleware([EnsureTokenIsValid::class]);
});
				
			

atau misal Jika anda mendaftarkan suatu middleware secara global lalu ingin mengecualikan middleware tersebut dari suatu grup route :

				
					use App\Http\Middleware\EnsureTokenIsValid;
 
Route::withoutMiddleware([EnsureTokenIsValid::class])->group(function () {
    Route::get('/profile', function () {
        //
    });
});
				
			

Metode withoutMiddleware hanya dapat menghapus middleware pada route dan tidak berlaku untuk middleware global

Grup Middleware

Misal anda mungkin ingin mengelompokkan beberapa middleware di bawah single key untuk membuatnya lebih mudah ditetapkan ke route. Anda dapat melakukannya dengan menggunakan properti $middlewareGroups dari kernel HTTP Anda.

Laravel menyertakan grup middleware web dan api yang telah ditentukan berisi middleware umum yang mungkin ingin Anda terapkan ke route web dan API Anda. Ingat, grup middleware ini secara otomatis diterapkan oleh service provider App\Providers\RouteServiceProvider ke dalam file route web dan api :

				
					/**
 * The application's route middleware groups.
 *
 * @var array
 */
protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
 
    'api' => [
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];
				
			

Grup middleware dapat ditugaskan ke route dan Controller menggunakan sintaks yang sama dengan middleware individual. Perlu diingat kembali, grup middleware membuat penggunaan banyak middleware ke sebuah route sekaligus menjadi lebih praktis :

				
					Route::get('/', function () {
    //
})->middleware('web');
 
Route::middleware(['web'])->group(function () {
    //
});
				
			
Pengurutan Middleware

Walaupun jarang ditemukan, ada kemungkuinan anda memerlukan middleware untuk berjalan dalam urutan tertentu  saat ditugaskan ke route. Dalam hal ini, Anda dapat menentukan prioritas middleware menggunakan properti $middlewarePriority dari file app/Http/Kernel.php. Properti ini mungkin tidak ada di kernel HTTP Anda secara default. Jika tidak ada, Anda dapat menyalin definisi standarnya di bawah ini:

				
					/**
 * The priority-sorted list of middleware.
 *
 * This forces non-global middleware to always be in the given order.
 *
 * @var string[]
 */
protected $middlewarePriority = [
    \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
    \Illuminate\Cookie\Middleware\EncryptCookies::class,
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    \Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class,
    \Illuminate\Routing\Middleware\ThrottleRequests::class,
    \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class,
    \Illuminate\Contracts\Session\Middleware\AuthenticatesSessions::class,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
    \Illuminate\Auth\Middleware\Authorize::class,
];
				
			
Parameter Middleware

Middleware juga dapat menerima parameter tambahan. Misalnya, jika aplikasi Anda perlu memverifikasi bahwa pengguna yang diautentikasi memiliki “peran” tertentu sebelum melakukan tindakan tertentu, Anda dapat membuat middleware SureUserHasRole yang menerima nama peran sebagai argumen tambahan.

Parameter middleware tambahan akan diteruskan ke middleware setelah argumen $next:

				
					<?php
 
namespace App\Http\Middleware;
 
use Closure;
 
class EnsureUserHasRole
{
    /**
     * Handle the incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string  $role
     * @return mixed
     */
    public function handle($request, Closure $next, $role)
    {
        if (! $request->user()->hasRole($role)) {
            // Redirect...
        }
 
        return $next($request);
    }
 
}
				
			

Parameter middleware dapat ditentukan saat menentukan rute dengan memisahkan nama dan parameter middleware dengan (:) misal role:editor. Beberapa parameter harus dipisahkan dengan koma(,) :

				
					Route::put('/post/{id}', function ($id) {
    //
})->middleware('role:editor');
				
			
Terminable Middleware

Terkadang middleware mungkin perlu melakukan beberapa pekerjaan setelah respons HTTP dikirim ke browser. Jika Anda telah menentukan metode penghentian pada middleware dan server web anda menggunakan FastCGI, metode penghentian akan dipanggil secara otomatis setelah respons dikirim ke browser :

				
					<?php
 
namespace Illuminate\Session\Middleware;
 
use Closure;
 
class TerminatingMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request);
    }
 
    /**
     * Handle tasks after the response has been sent to the browser.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Illuminate\Http\Response  $response
     * @return void
     */
    public function terminate($request, $response)
    {
        // ...
    }
}
				
			

Metode Terminate harus menerima kedua request dan respons. Setelah Anda menentukan middleware terminable, Anda harus mendaftarkannya ke route atau global middleware di file app/Http/Kernel.php.

Saat memanggil metode Terminate pada middleware, Laravel akan menyelesaikan instance middleware baru dari service container. Jika Anda ingin menggunakan instance middleware yang sama saat metode handle dan terminate dipanggil, daftarkan middleware dengan container menggunakan metode singleton container. Biasanya ini didaftarkan dalam metode register dari AppServiceProvider :

				
					use App\Http\Middleware\TerminatingMiddleware;
 
/**
 * Register any application services.
 *
 * @return void
 */
public function register()
{
    $this->app->singleton(TerminatingMiddleware::class);
}