Viết một đoạn code Middleware trong Laravel tổng hợp cả 3 quy tắc: domains_allow_all_routes, Restricted Domains và Allowed Routes để quyết định xem một request có được đi tiếp hay không.
Dưới đây là bản cài đặt hoàn chỉnh cho một "Master Middleware" trong Laravel. Middleware này sẽ đóng vai trò như một Gateway nội bộ, thực thi chính xác 3 lớp quy tắc bảo mật theo đúng thứ tự ưu tiên.
1. Lệnh khởi tạo
Tạo file Middleware. Chạy lệnh Artisan để tạo Middleware mới:
php artisan make:middleware AccessControlMiddleware
2. Viết mã xử lý
Triển khai logic lõi. Mở file app/Http/Middleware/AccessControlMiddleware.php và cập nhật đoạn code sau. Ở đây, chúng ta tận dụng sức mạnh của hàm Str::is() (hỗ trợ mảng pattern) để tối ưu code:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;
class AccessControlMiddleware
{
public function handle(Request $request, Closure $next): Response
{
// Lấy domain (host) và đường dẫn hiện tại của request
$currentHost = $request->getHost();
// Lấy path đảm bảo có dấu '/' ở đầu để so khớp chính xác
$currentPath = '/' . ltrim($request->path(), '/');
// 1. Load toàn bộ cấu hình từ file config (ví dụ: config/access_control.php)
$domainsConfig = config('access_control.domains', []);
$allowAllDomains = config('access_control.domains_allow_all_routes', []);
$restrictedDomains = config('access_control.restricted_domains', []);
$allowedRoutes = config('access_control.allowed_routes', []);
// --- LỚP 1: KIỂM TRA QUYỀN BYPASS (GOD MODE) ---
// Nếu host hiện tại nằm trong danh sách ưu tiên, cho phép đi qua ngay lập tức
if (in_array($currentHost, $allowAllDomains)) {
return $next($request);
}
// Tìm định danh (short identifier) của domain hiện tại (ví dụ: 'api', 'app')
// Nếu request đến từ một domain lạ không có trong config, ta gán là 'unknown'
$currentDomainId = array_search($currentHost, $domainsConfig) ?: 'unknown';
// --- LỚP 2: KIỂM TRA RESTRICTED DOMAINS (KIỂM SOÁT CHỦ THỂ) ---
// Kiểm tra xem định danh domain này có bị đưa vào danh sách hạn chế không
if (array_key_exists($currentDomainId, $restrictedDomains)) {
$permittedPatterns = $restrictedDomains[$currentDomainId];
// Hàm Str::is hỗ trợ truyền vào 1 mảng các pattern (wildcard)
if (!Str::is($permittedPatterns, $currentPath)) {
abort(403, "Access Denied: Domain '{$currentDomainId}' is restricted from accessing this route.");
}
}
// --- LỚP 3: KIỂM TRA ALLOWED ROUTES (KIỂM SOÁT MỤC TIÊU) ---
// Quét qua các route nhạy cảm xem request hiện tại có chạm vào không
foreach ($allowedRoutes as $routePattern => $permittedDomains) {
// Nếu đường dẫn request khớp với một pattern bảo mật
if (Str::is($routePattern, $currentPath)) {
// Kiểm tra xem domain hiện tại có nằm trong danh sách được phép gọi route này không
if (!in_array($currentDomainId, $permittedDomains)) {
abort(403, "Access Denied: Domain '{$currentDomainId}' is not allowed to access route pattern '{$routePattern}'.");
}
// Nếu khớp rule này rồi thì không cần check các rule bên dưới nữa
break;
}
}
// Vượt qua cả 3 lớp bảo vệ thành công
return $next($request);
}
}
3. Khai báo Middleware
Đăng ký vào hệ thống. Để hệ thống chạy đoạn code này trên mỗi request, bạn cần đăng ký nó vào app/Http/Kernel.php (hoặc bootstrap/app.php nếu dùng Laravel 11).
Ví dụ trong Laravel 10 (Kernel.php):
protected $middleware = [
// Các middleware khác...
\App\Http\Middleware\AccessControlMiddleware::class,
];
⚡ Phân tích độ phức tạp (Performance)
Đoạn code trên được tối ưu cực kỳ nhẹ. Các phép so sánh in_array, array_key_exists chạy với tốc độ hoặc rất nhỏ. Hàm Str::is() của Laravel sử dụng cache nội bộ cho các pattern Regex, giúp hệ thống không bị "nghẽn cổ chai" (bottleneck) ngay cả khi phải xử lý hàng nghìn request mỗi giây tại tầng Gateway.
All Rights Reserved