Middleware trong Laravel 8

Nếu bạn còn nhớ trong bài Route mình đã từng nhắc đến Middleware và hứa sẽ trình bày sau và hôm nay mình sẽ thực hiện lời hứa đó. Trong bài này chúng ta sẽ tìm hiểu về Middleware trong Laravel 8 các bạn nhé!

1. Middleware trong Laravel 8 là gì?

Trong Laravel 8 middleware cung cấp một cơ chế thuận tiện để kiểm tra và lọc các HTTP request đến ứng dụng của bạn.

Ví dụ: Laravel bao gồm một middleware Authenticate có tác dụng xác minh người dùng ứng dụng của bạn đăng nhập hay chưa. Nếu người dùng chưa đăng nhập, phần mềm trung gian sẽ chuyển hướng người dùng đến màn hình đăng nhập ứng dụng của bạn. Tuy nhiên, nếu người dùng đã đăng nhập middleware sẽ cho phép thực hiện các request (yêu cầu) tiếp theo.

Trong Laravel, tất cả các middleware sẽ được đặt trong thư mục app/Http/Middleware.

2. Khai báo middleware trong Laravel 8

Để tạo middleware trong Laravel chúng ta sử dụng lệnh command sau:

php artisan make:middleware MiddlewareName

Với  MiddlewareName là tên của middleware các bạn muốn tạo.

Ví DỤ: Dưới đây chúng ta sẽ tạo một middleware có name là  EnsureTokenIsValid.

php artisan make:middleware EnsureTokenIsValid

Sau lệnh này Laravel 8 sẽ sinh ra cho bạn một file middleware nằm trong thư mục app/Http/Middleware với tên file là EnsureTokenIsValid.php và có nội dung như sau

<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;


class EnsureTokenIsValid
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        return $next($request);
    }
}

Trong đó: return $next($request) chính là đoạn code cho phép request tiếp tục được thực thi.

Ví DỤ : Mình sẽ redirect về URL /trangchukhi request không có token, hoặc token không phải bằng 'hoc.tv'.

<?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') !== 'hoc.tv') {
            return redirect('trangchu');
        }

        return $next($request);
    }
}

Lúc này khi bạn gửi request nếu không có input token hoặc input token không phải là hoc.tv thì request sẽ được redirect về URL có path /trangchu.

3. Đăng ký middlware.

Để đăng ký middlware vào trong app chúng ta cần khai báo chúng ở trong file app/Http/Kernel.php. Mặc định, Laravel có 3 loại middleware chính là:

  • Global middleware: Các middlware được khai báo trong thuộc tính $middleware là global middleware, các middleware này sẽ được thực thi cho tất cả request.
  • Group middleware: Các middlware được khai báo trong thuộc tính $middlewareGroups sẽ được thực thi khi chúng ta gọi chúng. Mặc định thì Laravel định nghĩa ra 2 group là web và api tương ứng với các route trong web.php và api.php.
  • Route middleware: Các middlware được khai báo trong thuộc tính $routeMiddleware sẽ được thực thi khi chúng ta gọi tên chúng.

Ví dụ : Chúng ta sẽ khai báo middleware EnsureTokenIsValid vào trong $routeMiddleware với name là 'validate_token'.

/**
 * The application's route middleware.
 *
 * These middleware may be assigned to groups or used individually.
 *
 * @var array
 */
protected $routeMiddleware = [
    //...
    //...
    'validate_token' => \App\Http\Middleware\EnsureTokenIsValid::class
];

Lúc này nếu route nào cần dùng chỉ cần khai báo middleware là 'validate_token' là được.

VD:

Route::get('/user', function () {
    //
})->middleware('validate_token');

4. Mức độ ưu tiên middleware.

Mặc định các middleware sẽ được thực thi theo thứ tự từ trên xuống. Nhưng nếu muốn bạn vẫn có thể thay đổi thứ tự ưu tiên của một middleware nào đó được. Trong trường hợp này, bạn có thể chỉ định mức độ ưu tiên middleware của mình bằng cách sử dụng thuộc tính $middlewarePriority  của tệp ứng dụng / Http / Kernel.php của bạn. Thuộc tính này có thể không tồn tại trong hạt nhân HTTP theo mặc định. Nếu nó không tồn tại, bạn có thể sao chép định nghĩa mặc định của nó bên dưới:

Bạn có thể thêm vào trong thuộc tính $middlewarePriority trong file app/Http/Kernel.php

Ví Dụ:

/**
 * The priority-sorted list of middleware.
 *
 * This forces non-global middleware to always be in the given order.
 *
 * @var array
 */
protected $middlewarePriority = [
    \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\Session\Middleware\AuthenticateSession::class,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
    \Illuminate\Auth\Middleware\Authorize::class,
];

Chú ý: $middlewarePriority chỉ làm việc đối với middleware không phải global.

5. Middleware Parameter.

Chúng ta cũng có thể truyền thêm tham số vào middleware để thực thi các logic cho từng tham số đó. Bạn có thể tham khảo ví dụ sau.

Ví Dụ: thêm tham số $redirectTo vào middleware EnsureTokenIsValid ở trên.

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class EnsureTokenIsValid
{
    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request
     * @param Closure $next
     * @param string $redirectTo
     * @return mixed
     */
    public function handle(Request $request, Closure $next, $redirectTo = 'home')
    {
        if ($request->input('token') !== 'hoc.tv') {
            return redirect($redirectTo);
        }
        return $next($request);
    }
}

Lúc này khi gọi middleware chúng ta có thể truyền thêm tham số vào middleware 

Route::get('/', function () {
    return redirect()->back();
})->middleware('validate_token:/login');

Trong đó: đằng sau dấu : (hai chấm) sẽ là tham số truyền vào middleware, nếu middleware có nhiều tham số truyền vào bạn có thể sử dụng dấu , để ngăn cách giữa các biến.

6. Terminable Middleware

Đôi khi một Middleware có thể cần thực hiện một số công việc sau khi phản hồi HTTP đã được gửi đến trình duyệt. Nếu bạn xác định phương thức terminate  trên Middleware của mình và máy chủ web của bạn đang sử dụng FastCGI, phương thức terminate  sẽ tự động được gọi sau khi phản hồi được gửi đến trình duyệt:

<?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)
    {
        // ...
    }
}

Terminable Middleware cần phải khai báo trong  app/Http/Kernel.php và khi được gọi cần phải đăng ký trong AppServiceProvider

use App\Http\Middleware\TerminatingMiddleware;

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

6. Lời kết.

Tóm lại các middleware trong Laravel 8 giống như một bốt trung gian để kiểm tra và lọc các HTTP request đến ứng dụng của bạn. Có thể nói middleware là chốt chặn đầu tiên để xử lý request của người dùng trước khi cho phép người dùng thực hiện các việc lớn lao hơn.

Bình luận