Tìm kiếm bài viết

Laravel: Tìm hiểu về Middleware

12.10.2020

0/5 (0 Reviews)

Nếu ai làm lập trình, thiết kế website bằng laravel thì chắc là đã nghe qua về Middleware rồi chứ nhỉ. Middleware cung cấp một giải pháp khá tiện ích cho việc filtering

    Tìm hiểu về Middleware trong Laravel

    Nếu ai làm lập trình, thiết kế website bằng laravel thì chắc là đã nghe qua về Middleware rồi chứ nhỉ. Middleware cung cấp một giải pháp khá tiện ích cho việc filtering HTTP các requests trong ứng dụng của bạn. Ví dụ, Laravel có chứa một middleware xác thực user đăng nhập vào ứng dụng của bạn được chứng thực. Nếu user chưa được chứng thực, middleware sẽ chuyển hướng (redirect) user tới màn hình đăng nhập. Tuy nhiên, nếu user đã được chứng thực, middleware sẽ cho phép request được thực hiện tiếp tiến trình xử lý vào ứng dụng.

    Tất nhiên, bạn có thể viết thêm middleware để thực hiện nhiều tác vụ khác ngoài việc xác thực vào hệ thống. Một CORS middleware có trách nhiệm thêm các header thích hợp vào trong tất cả các response gửi ra ngoài ứng dụng của bạn. Một logging middleware có thể ghi log cho tất cả các request tới ứng dụng của bạn.

    Có một số middleware đã có sẵn trong Laravel framework, bao gồm middlware xác thực và CSRF protection. Tất cả các middleware này đều được nằm trong thư mục app/Http/Middleware.

    Defining Middleware

    Để tạo mới một middleware, sử dụng câu lệnh artisan make:middleware :

    php artisan make:middleware CheckAge
    

    Câu lệnh này sẽ đặt 1 class mới CheckAge trong thư mục app/Http/Middleware. Trong middleware này, chúng ta chỉ cho phép truy cập đến route nếu cung cấp age lớn hơn 200. Nếu không thì, chúng ta sẽ chuyển hướng user trở lại trang home.

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

    Như bạn thấy, nếu age nhỏ hơn hoặc bằng 200, middleware sẽ trả về một HTTP redirect tới client; nếu không thì, request sẽ được chuyển tiếp vào ứng dụng của bạn. Để truyền request vào sâu hơn trong ứng dụng (cho phép middleware "vượt qua"), đơn giản chỉ cần gọi $next callback với $request.

    Tốt nhất hãy hình dung middleware như một chuỗi các "lớp" HTTP requests phải vượt qua trước khi vào ứng dụng. Mỗi lớp sẽ được kiểm tra request và thậm chí có thể từ chối request hoàn toàn.

    Before và After trong Middleware

    Việc middleware chạy trước hay chạy sau một request phụ thuộc vào middleware đó. Ví dụ, middleware sau sẽ thực hiện một số tác vụ trước khi request được chương trình xử lý:

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

    Tuy nhiên, middleware này sẽ thực hiện nhiệm vụ của nó sau khi request được xử lý bởi ứng dụng:

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

    Registering Middleware trong laravel thế nào?

    Global Middleware

    Nếu bạn muốn một middleware có thể thực thi trong mọi HTTP request tới ứng dụng của bạn, đơn giản chỉ cần liệt kê tên class middleware trong thuộc tính $middleware của class app/Http/Kernel.php.

    Assigning Middleware To Routes

    Nếu bạn muốn gán middleware cho route cụ thể, đầu tiên bạn cần thêm middleware đó là 1 key trong file app/Http/Kernel.php. Mặc định, thuộc tính $routeMiddleware chứa một số class middleware có sẵn trong Laravel. Để thêm middleware của bạn, đơn giản chỉ là thêm nó vào dach sách và gán từ khóa bạn chọn. Ví dụ:

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

    Mỗi middleware được định nghĩa trong HTTP kernel, bạn có thể sử dụng phương thức middleware để chỉ định middleware cho một route:

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

    Bạn cũng có thể chỉ định nhiều middleware cho route:

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

    Khi chỉ định middleware cho route, bạn cũng có thể sử dụng tên đầy đủ của class middleware:

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

    Middleware Groups

    Đôi khi có thể bạn muốn nhóm một vài middleware lại trong một key để thực hiện gán vào route dễ dàng hơn. Bạn có thể sử dụng thuộc tính ```$middlewareGroups``` của HTTP kernel.

    Ngoài ra, Laravel đi kèm với các nhóm middleware webapi có chứa các middleware phổ biến mà bạn có thể áp dụng cho giao diện người dùng trên các route web và các api của mình:

    /**
     * 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:60,1',
            'auth:api',
        ],
    ];
    

    middleware group được gán vào routes và controller sử dụng cú pháp tương tự như với middleware đơn lẻ. Một lần nữa, middleware group làm đơn giản trong việc gán các middleware vào trong một route:

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

    Middleware Parameters

    Middleware cũng có thể nhận thêm các tham số truyền vào. Ví dụ, nếu ứng dụng của bạn cần xác thực có "role" cụ thể trước khi thực hiện một thao tác nào đó, bạn có thể tạo một CheckRole middleware để nhận tên của role như một tham số.

    Thêm các tham số middleware sẽ được truyền vào middleware ngay sau tham số $next của hàm handle:

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    
    class CheckRole
    {
        /**
         * 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);
        }
    
    }
    

    Tham số middleware có thể được khai báo trên route bằng cách phân chia tên middleware và tham số bởi dấu :. Nhiều tham số thì cần được phân chia bởi dấy phẩy:

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

    Terminable Middleware

    Đôi khi một middleware có thể cần thực hiện sau khi HTTP response đã được gửi xong cho trình duyệt. Ví dụ, "session" middleware có trong Laravel ghi dữ liệu session cho storage sau khi response được gửi tới trình duyệt. Nếu bạn định nghĩa một phương thức terminate vào trong middleware, nó sẽ tự động được gọi sau khi response được gửi tới trình duyệt.

    <?php
    
    namespace Illuminate\Session\Middleware;
    
    use Closure;
    
    class StartSession
    {
        public function handle($request, Closure $next)
        {
            return $next($request);
        }
    
        public function terminate($request, $response)
        {
            // Store the session data...
        }
    }
    

    Phương thức terminate có thể nhận cả request và response. Mỗi khi bạn định nghĩa terminable middleware, bạn cần thêm vào danh sách global middleware trong file app/Http/Kernel.php.

    Khi bạn gọi hàm terminate trong middleware, Laravel sẽ giải quyết instance mới cho middleware từ . Nếu bạn muốn sử dụng cùng một middleware instance khi mà phương thức handleterminate được gọi, hãy đăng ký middleware vào trong container sử dụng phương thức singleton.

    CÓ THỂ BẠN QUAN TÂM

    Bài Viết Cùng Chuyên Mục

    XEM THÊM
    thumbnail

    Kubernetes bài 6 - Vận hành k8s Day-Two Operations và Quản trị bằng GitOps

    22.05.2026

    Khi cụm Kubernetes của bạn đã được bảo mật cấu hình, tối ưu tài nguyên và thiết lập tự phục hồi, câu hỏi đặt ra là làm sao để duy trì sự ổn định đó trong nhiều năm tiếp theo mà không bị phụ thuộc

    thumbnail

    Kubernetes bài 5 - bảo mật Cloud Native và chuẩn DevSecOps cho K8s

    22.05.2026

    Việc siết chặt an ninh (Hardening) không phải là cấu hình một vài thông số rồi bỏ đó, mà là một tư duy phòng thủ chiều sâu.

    thumbnail

    Kubernetes bài 4 - Tối ưu Resource Auto-Healing và Scale Zero-Downtime

    22.05.2026

    Bài viết này sẽ đi sâu vào các cơ chế ở tầng Kernel giúp hệ thống tự phục hồi, chống lại các đợt tấn công cạn kiệt tài nguyên và cập nhật phiên bản mới mà người dùng không hề hay biết.

    thumbnail

    Kubernetes bài 3 - Bảo mật cấu hình k8s và config Security trên Production

    22.05.2026

    Kubernetes giải quyết bài toán này bằng hai đối tượng chuyên biệt nhưng nếu không hiểu rõ bản chất bảo mật ở tầng dưới, bạn đang tự tay dâng toàn bộ chìa khóa hệ thống cho hacker.

    thumbnail

    Kubernetes bài 2 - Mạng lưới k8s và luồng Traffic ở Packet Level

    22.05.2026

    Pod không chỉ là một container: Rất nhiều người nhầm lẫn Pod 1-1 với Container. Thực chất, Pod là đơn vị triển khai nhỏ nhất, có thể chứa một hoặc nhiều container

    Mục lục bài viết