Middleware là gì? Tại sao phải sử dụng nó?

Middleware là gì? Tại sao phải sử dụng nó?
Như tiêu đề của bài viết hôm chúng ta cùng nhau tìm hiểu về middleware và middleware được thể hiện như thế nào trong Laravel nhé.

Như tiêu đề của bài viết hôm chúng ta cùng nhau tìm hiểu về middleware và middleware được thể hiện như thế nào trong Laravel nhé.


Middleware là gì?


Trước khi trả lời cho câu hỏi đó chúng ta hãy cùng tưởng tượng nếu bạn đang code một trang về bán hàng và trước khi người dùng thực hiện các chức năng:
- Lấy danh sách sản phẩm
- Đăng bán sản phẩm
- Để lại bình luận dưới sản phẩm


Bạn phải kiểm tra xem người dùng đã đăng nhập hay chưa. Bạn sẽ giải quyết nó như thể nào, copy và paste điều kiện vào function của những chức năng đó? Giả sử không phải 3 mà là 30 chức năng thì việc copy paste đó quá rườm rà đúng không

Vì vậy Middleware ra đời để giúp bạn giải quyết vấn đề đó. Middleware là những đoạn mã trung gian nằm giữa các request và response. Nó nhận các request, thi hành các mệnh lệnh tương ứng trên request đó. Sau khi hoàn thành nó response (trả về) hoặc chuyển kết quả ủy thác cho một Middleware khác trong hàng đợi.

Middleware được thể hiện như thế nào trong Laravel?

Để tạo một Middleware trong Laravel ta sử dụng câu lệnh:

php artisan make:middleware MiddlewareName

File middleware được khởi tạo sẽ có dạng như sau:

app/Http/Middleware/MiddleawareName.php

<?php
namespace App\Http\Middleware;
class XXX
{
    public function handle(Request $request, Closure $next){
      // your logic go here...
    }
}

Việc viết hàm/logic diễn ra bình thường, chỉ có điều xuất hiện thêm 1 parameter $next, được dùng để đánh dấu logic của controller. $next sẽ hoạt động như 1 calllback và sẽ gọi để kích hoạt hàm tiếp theo.

Chúng ta cần đăng ký middleware với hệ thống trước khi sử dụng chúng, có hai loại middleware:

  • Global middleware là middleware sẽ được sử dụng với bất kể yêu cầu HTTP đến hệ thống, đơn giản là thêm middleware này vào thuộc tính $middleware trong class app/Http/Kernel.php.
  • Route middleware là gắn một middleware với một route xác định, trước khi gắn một route với một middleware phải liệt kê chúng vào thuộc tính $routeMiddleware trong class app/Http/Kernel.php.

Nội dung file app/Http/Kernel.php và xem cách đăng ký Middleware:

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{

    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::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,
        <strong>'MiddleawareName' => \App\Http\Middleware\MiddleawareName::class,</strong>
    ];
}

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 /routes/web.php và /routes/api.php.

Thứ tự thực thi của các middleware:

Thông thường middleware sẽ được thực thi theo thứ tự từ trên xuống. Nhưng nếu bạn muốn thay đổi thứ tự ưu tiên của một middleware nào đó. Bạn có thể thêm vào trong thuộc tính $middlewarePriority trong file app/Http/Kernel.php. Thuộc tính này có thể không tồn tại trong HTTP kernel của bạn theo mặc định. Nếu nó không tồn tại, bạn có thể định nghĩa như bên dưới:

/**
 * 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,
];

Middleware parameter:

Middleware cũng có thể nhận các parameter. Ví dụ: nếu ứng dụng của bạn cần xác minh rằng người dùng được xác thực có “role” nhất định trước khi thực hiện một hành động nhất định, bạn có thể tạo EnsureUserHasRole middleware nhận tên vai trò như một đối số bổ sung.

<?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);
    }

}

Như đoạn code ở trên các Middleware parameter có thể được chỉ định khi xác định route bằng cách tách tên middleware và các parameter bằng dấu hai chấm(:). Nếu nhiều tham số phải được phân cách bằng dấu phẩy (,) :

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

 

 

Qua bài vừa rồi hi vọng có thể giúp bạn hiểu hơn về Middleware trong Laravel. Nhớ đừng quên theo dõi hoclaravel.vn để xem được những bài viết bổ ích hơn nữa nhé.

Các bạn cũng có thể để lại câu hỏi nếu có bất cứ thắc mắc nào ở phần bình luận phía dưới.

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{

    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::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,
        'MiddleawareName' => \App\Http\Middleware\MiddleawareName::class,
    ];
}

Đào Hữu Hải

Dev cùi tập tành làm nhà văn :D

Bình luận (2)