Middleware
1. Middleware là gì?
Middleware hoạt động như một cơ chế lọc (filter) các HTTP request đi vào hệ thống. Trước khi request đến được Application Logic hoặc Controller, nó sẽ đi qua nhiều tầng Middleware. Bạn có thể sử dụng Middleware để:
- Xác thực người dùng (kiểm tra đăng nhập)
- Phân quyền (Roles / Permissions)
- Bảo vệ khỏi tấn công (CSFR Token, XSS Sanitization)
- Lưu Log, thống kê người dùng truy cập...
Ví dụ, SkillDo CMS đi kèm một middleware để xác nhận user đã đăng nhập. Nếu user chưa xác thực, middleware sẽ chuyển hướng người dùng trở lại màn hình đăng nhập. Ngược lại, nếu xác thực hợp lệ, request được chuyển tiếp vào ứng dụng.
2. Cách Tạo & Cơ Chế Hoạt Động của Middleware
Một Middleware luôn yêu cầu tồn tại phương thức handle($request, \Closure $next).
Sau khi kiểm tra điều kiện, để truyền Request đi tiếp trong pipeline, ta gọi return $next($request). Hoặc trả về redirect thì ta trả về Response mong muốn và kết thúc chu kì.
<?php
namespace SkillDo\Http\Middlewares;
use SkillDo\Http\Request;
use Closure;
class ExampleMiddleware
{
/**
* Handle an incoming request.
*
* @param \SkillDo\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
// Kiểm tra logic...
if ($request->input('age') <= 200) {
return redirect('home'); // Không hợp lệ: Từ chối / Redirect
}
return $next($request); // Hợp lệ: Tiếp tục tới tầng tiếp theo
}
}
3. Cách Sử Dụng Middleware
3.1. Gắn vào Route
Để gán Middleware vào một Route nhất định, ta sử dụng method ->middleware().
Có thể đưa vào Tên Class FQN, hoặc các Chuỗi (Alias / Group) định danh.
use SkillDo\Http\Middlewares\ExampleMiddleware;
// 1. Dùng tên class trực tiếp
Route::get('/profile', function () {
//
})->middleware(ExampleMiddleware::class);
// 2. Dùng Alias (bí danh)
Route::get('/dashboard', function () {})->middleware('auth:admin');
// 3. Gắn cho cả một mảng chung (Route Group)
Route::middleware(['auth:admin', 'admin.permission'])->group(function () {
Route::get('/settings', function () {});
});
3.2. Đăng Ký Cấu Hình Hệ Thống (Global & Defaults)
Trên SkillDo CMS v8, các cấu hình chung của hệ thống nằm trong file bootstrap/app.php. Nơi này hỗ trợ bạn tùy biến Middleware Pipeline tổng bằng \SkillDo\Configuration\Middleware.
// File: bootstrap/app.php
->withMiddleware(function (\SkillDo\Configuration\Middleware $middleware) {
// Thêm middleware chạy trên toàn bộ hệ thống
$middleware->append(GlobalMyCustomMiddleware::class);
// Thêm middleware vào riêng Group "web" hoặc "api"
$middleware->appendToGroup('web', LogVisitMiddleware::class);
// Gán các bí danh (aliases) tùy chỉnh
$middleware->alias([
'admin.auth' => \SkillDo\Cms\Http\Middleware\AdminAuth::class,
]);
})
4. Đăng Ký Middleware Trong Plugin
Khi xây dựng Plugin, chúng ta không can thiệp vào bootstrap/app.php mà khai báo các Middleware qua file plugin.json. CMS Loader sẽ tự động đăng ký vào Router khi Plugin kích hoạt.
Tùy chọn thiết lập bao gồm nhóm vào các groups (thường là nhóm chung cho web hoặc api) và gán alias (route).
// File: plugins/my-plugin/plugin.json
{
"name": "My Plugin",
"class":"MyPlugin",
"middlewares": {
"groups": {
"web": [
"MyPlugin\\Middlewares\\TrackVisitor"
],
"api": [
"MyPlugin\\Middlewares\\ApiRateLimiter"
]
},
"route": {
"my_plugin_auth": "MyPlugin\\Middlewares\\PluginAuthMiddleware"
}
}
}
Giải thích:
- Các Middleware bên trong
"groups": {"web": [...]}sẽ được chạy trên tất cả các Route Frontend của hệ thống thuộc nhóm web. - Middleware được cấu hình trong
"route": {"bí_danh": "..."}sẽ được đăng ký như 1 Alias để sau này dùng:Route::get(...)->middleware('my_plugin_auth').
5. Đăng Ký Middleware Trong Theme
Nhằm đảm bảo hiệu suất và cấu trúc chuẩn cho Theme, Middleware của Theme sẽ được thiết lập tự do thông qua cấu hình ThemeConfig bằng đối tượng khởi tạo file views/theme-store/theme.json hoặc trong Service Provider/Helper tùy chọn của Theme.
Để thông báo cho cấu hình Loader đăng ký Middleware, ta có thể set giá trị trong Theme Config.
Cách làm chuẩn là trong các function cấu hình theme (vd: file functions.php), gọi hàm của themeConfig:
// Ví dụ khai báo Middleware trong theme (vd trong function boot)
app('themeConfig')->set('middleware', [
'groups' => [
'web' => [
\Theme\Middlewares\ThemeSetupMiddleware::class,
],
],
'route' => [
'theme_auth' => \Theme\Middlewares\ThemeAuthMiddleware::class,
]
]);
- Namespace chuẩn của File code phải nằm trong:
views/theme-store/app/Middlewares/ThemeSetupMiddleware.phpvới cấu trúc tương tự ở phần 2. - Hệ thống hỗ trợ hoàn toàn việc đẩy Alias lên Router cho người làm Theme thoải mái gọi vào
routes/web.phptrong theme.