Laravel Middleware Chi Tiết: Xác Thực, Rate Limiting và Custom Middleware
Hướng dẫn toàn diện về Laravel middleware với các ví dụ thực tế về authentication guard, rate limiting với throttle, tạo custom middleware, PHP attribute trong Laravel 13, và các pattern nâng cao cho ứng dụng production.

Middleware trong Laravel đóng vai trò như một lớp lọc giữa các HTTP request đến và logic xử lý của ứng dụng. Mỗi request đều phải đi qua một chuỗi các lớp middleware trước khi tới được controller, và mỗi response cũng đi ngược lại qua chính chuỗi đó. Việc nắm vững cơ chế này là điều thiết yếu để xây dựng các ứng dụng Laravel an toàn và có hiệu suất cao.
Middleware chặn các HTTP request trước khi chúng tới được route. Laravel đăng ký toàn bộ middleware trong bootstrap/app.php thông qua fluent API. Các middleware tích hợp sẵn xử lý authentication, bảo vệ CSRF, quản lý session và rate limiting ngay khi cài đặt.
Cơ Chế Hoạt Động Của Middleware Pipeline Trong Laravel
HTTP kernel của Laravel xử lý mỗi request thông qua một stack middleware. Mỗi middleware nhận request, thực hiện logic của mình, rồi chuyển request sang lớp tiếp theo thông qua $next($request) hoặc cắt ngang pipeline bằng cách trả về response trực tiếp.
Kiến trúc này tuân theo pattern Chain of Responsibility. Middleware có thể hoạt động trước khi request đến controller (ví dụ: kiểm tra authentication), sau khi response được tạo (ví dụ: thêm header), hoặc cả hai.
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;
class LogRequestTime
{
public function handle(Request $request, Closure $next): Response
{
$start = microtime(true); // Capture start time
$response = $next($request); // Pass to next middleware
$duration = microtime(true) - $start;
Log::info('Request completed', [
'url' => $request->url(),
'method' => $request->method(),
'duration' => round($duration * 1000, 2) . 'ms',
]);
return $response; // Return response up the stack
}
}Middleware trên bao bọc request: ghi lại thời gian bắt đầu trước khi xử lý và ghi lại thời lượng sau khi response được trả về. Pattern before/after này là cốt lõi của cách middleware hoạt động.
Authentication Middleware: Bảo Vệ Route
Laravel cung cấp sẵn middleware alias auth, được ánh xạ tới Illuminate\Auth\Middleware\Authenticate. Khi áp dụng middleware này cho một route, chỉ những người dùng đã xác thực mới có thể truy cập. Người dùng chưa xác thực sẽ nhận response 401 (đối với API) hoặc được chuyển hướng tới trang đăng nhập (đối với web).
use App\Http\Controllers\DashboardController;
use App\Http\Controllers\ProfileController;
// Single route protection
Route::get('/dashboard', [DashboardController::class, 'index'])
->middleware('auth');
// Group protection for multiple routes
Route::middleware('auth')->group(function () {
Route::get('/profile', [ProfileController::class, 'show']);
Route::put('/profile', [ProfileController::class, 'update']);
Route::delete('/profile', [ProfileController::class, 'destroy']);
});Xác Thực Đa Guard
Các ứng dụng có nhiều loại người dùng (panel quản trị, khu vực khách hàng, API) cần sử dụng xác thực dựa trên guard. Middleware auth chấp nhận tham số guard để chỉ định driver xác thực nào sẽ được sử dụng.
// API routes use the 'sanctum' guard
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', fn (Request $request) => $request->user());
Route::apiResource('/orders', OrderController::class);
});
// routes/web.php
// Admin routes use a custom 'admin' guard
Route::middleware('auth:admin')->prefix('admin')->group(function () {
Route::get('/dashboard', [AdminController::class, 'index']);
Route::get('/users', [AdminController::class, 'users']);
});Tham số guard sau dấu hai chấm cho Laravel biết cấu hình xác thực nào cần kiểm tra. Cách tiếp cận này giữ logic xác thực gọn gàng và tách biệt giữa các phần khác nhau của ứng dụng.
Middleware guest là nghịch đảo của auth, chỉ cho phép người dùng chưa xác thực đi qua. Áp dụng middleware này cho các route đăng nhập và đăng ký giúp ngăn người dùng đã xác thực truy cập lại những trang đó.
Rate Limiting Với Throttle Middleware
Rate limiting trên middleware Laravel bảo vệ các route khỏi sự lạm dụng bằng middleware throttle tích hợp sẵn. Dạng đơn giản nhất chấp nhận hai tham số: số lượng request tối đa và khung thời gian tính bằng phút.
// Allow 60 requests per minute per user
Route::middleware('throttle:60,1')->group(function () {
Route::get('/posts', [PostController::class, 'index']);
Route::get('/posts/{post}', [PostController::class, 'show']);
});
// Stricter limit for write operations
Route::middleware(['auth:sanctum', 'throttle:10,1'])->group(function () {
Route::post('/posts', [PostController::class, 'store']);
Route::put('/posts/{post}', [PostController::class, 'update']);
});Named Rate Limiters Cho Kiểm Soát Nâng Cao
Việc định nghĩa named rate limiters trong AppServiceProvider mang lại khả năng kiểm soát chi tiết dựa trên ngữ cảnh người dùng. Cách tiếp cận này linh hoạt hơn nhiều so với việc truyền tham số throttle trực tiếp. Xem tài liệu rate limiting chính thức để biết thêm các tùy chọn.
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Http\Request;
public function boot(): void
{
// API rate limiter with tiered access
RateLimiter::for('api', function (Request $request) {
$user = $request->user();
if ($user?->hasSubscription('enterprise')) {
return Limit::perMinute(500)->by($user->id); // Enterprise: 500/min
}
if ($user) {
return Limit::perMinute(100)->by($user->id); // Authenticated: 100/min
}
return Limit::perMinute(20)->by($request->ip()); // Anonymous: 20/min
});
// Login limiter to prevent brute force
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)
->by($request->ip()) // Key by IP address
->response(function () { // Custom exceeded response
return response()->json([
'message' => 'Too many login attempts. Try again in a minute.',
], 429);
});
});
}Các named limiter được áp dụng cho route thông qua cú pháp throttle:name:
Route::middleware('throttle:api')->group(function () {
Route::apiResource('/posts', PostController::class);
});
// routes/web.php
Route::middleware('throttle:login')
->post('/login', [AuthController::class, 'login']);Tiered rate limiter ở trên thể hiện một pattern production: người dùng enterprise nhận limit cao hơn, người dùng đã xác thực nhận limit vừa phải, và các request ẩn danh bị hạn chế nghiêm ngặt. Phương thức by() xác định rate limit key, sử dụng user ID cho người dùng đã xác thực và địa chỉ IP làm phương án dự phòng.
Sẵn sàng chinh phục phỏng vấn Laravel?
Luyện tập với mô phỏng tương tác, flashcards và bài kiểm tra kỹ thuật.
Xây Dựng Custom Middleware Từ Đầu
Việc tạo custom middleware bao gồm các tình huống mà middleware tích hợp sẵn không xử lý được. Lệnh Artisan make:middleware tạo ra một class mới với cấu trúc đúng.
php artisan make:middleware EnsureUserHasRoleMiddleware Kiểm Soát Truy Cập Theo Vai Trò
Một pattern phổ biến cho custom middleware là kiểm soát quyền truy cập dựa trên vai trò (role-based authorization) ở cấp route, với việc nhận tên role làm tham số.
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class EnsureUserHasRole
{
public function handle(Request $request, Closure $next, string ...$roles): Response
{
$user = $request->user();
if (! $user || ! $user->hasAnyRole($roles)) {
abort(403, 'Insufficient permissions.');
}
return $next($request);
}
}Tham số variadic ...$roles cho phép truyền nhiều role cách nhau bằng dấu phẩy. Việc đăng ký và sử dụng như sau:
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'role' => App\Http\Middleware\EnsureUserHasRole::class,
]);
})
// routes/web.php
Route::middleware('role:admin')->group(function () {
Route::get('/admin', [AdminController::class, 'index']);
});
// Multiple roles: admin OR editor can access
Route::middleware('role:admin,editor')->group(function () {
Route::resource('/articles', ArticleController::class);
});Middleware Biến Đổi Request
Middleware có thể sửa đổi request trước khi nó tới controller. Một middleware cho JSON API kiểm tra content type header và làm sạch các chuỗi đầu vào bằng cách loại bỏ khoảng trắng thừa:
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class ApiRequestSanitizer
{
public function handle(Request $request, Closure $next): Response
{
// Reject non-JSON requests on API routes
if (! $request->expectsJson() && $request->isMethod('POST')) {
return response()->json(
['error' => 'Content-Type must be application/json'],
415
);
}
// Trim all string inputs
$input = $request->all();
array_walk_recursive($input, function (&$value) {
if (is_string($value)) {
$value = trim($value);
}
});
$request->merge($input);
return $next($request);
}
}Middleware này xử lý hai vấn đề cùng lúc: kiểm tra content type cho các POST request và làm sạch tất cả đầu vào dạng chuỗi bằng cách trim khoảng trắng.
Đăng Ký Middleware Trong bootstrap/app.php
Laravel tập trung toàn bộ đăng ký middleware trong bootstrap/app.php. Cách tiếp cận này thay thế phương pháp cũ sử dụng app/Http/Kernel.php trước Laravel 11. Fluent API tương tự hoạt động trong Laravel 12 và 13.
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withMiddleware(function (Middleware $middleware) {
// Global middleware (runs on every request)
$middleware->append(
App\Http\Middleware\LogRequestTime::class
);
// Add to the 'web' middleware group
$middleware->web(append: [
App\Http\Middleware\TrackPageViews::class,
]);
// Add to the 'api' middleware group
$middleware->api(prepend: [
App\Http\Middleware\ApiRequestSanitizer::class,
]);
// Register aliases for route-level use
$middleware->alias([
'role' => App\Http\Middleware\EnsureUserHasRole::class,
'subscribed' => App\Http\Middleware\EnsureUserIsSubscribed::class,
]);
// Control execution order
$middleware->priority([
Illuminate\Session\Middleware\StartSession::class,
Illuminate\Auth\Middleware\Authenticate::class,
App\Http\Middleware\EnsureUserHasRole::class,
]);
})
->create();Mảng priority có vai trò quan trọng khi nhiều middleware được gán cho cùng một route. Laravel sắp xếp chúng theo danh sách này, đảm bảo session được khởi tạo trước khi xác thực chạy, và xác thực hoàn tất trước khi kiểm tra vai trò.
Middleware chạy theo thứ tự được đăng ký. Đối với middleware cấp route, mảng priority ghi đè thứ tự mặc định. Luôn đặt authentication middleware trước authorization middleware để tránh kiểm tra vai trò trên các request chưa xác thực.
PHP Attributes Cho Middleware Trong Laravel 13
Laravel 13 giới thiệu PHP attribute #[Middleware] để khai báo middleware trực tiếp trên class và method controller. Cách tiếp cận này giữ cấu hình middleware cùng chỗ với code mà nó bảo vệ, giúp các quy tắc ủy quyền dễ đọc và bảo trì hơn.
namespace App\Http\Controllers;
use App\Models\Comment;
use App\Models\Post;
use Illuminate\Routing\Attributes\Controllers\Authorize;
use Illuminate\Routing\Attributes\Controllers\Middleware;
#[Middleware('auth')]
class CommentController
{
#[Middleware('subscribed')]
#[Authorize('create', [Comment::class, 'post'])]
public function store(Post $post)
{
// Only authenticated, subscribed users who can create comments reach here
}
public function index(Post $post)
{
// Still requires auth (from class-level attribute)
return $post->comments;
}
}#[Middleware('auth')] ở cấp class áp dụng cho tất cả các method. Các attribute ở cấp method được chồng lên trên: store() yêu cầu cả auth và subscribed. Attribute #[Authorize] tích hợp với hệ thống policy của Laravel, kiểm tra quyền trước khi method thực thi.
Cách tiếp cận dựa trên attribute này là tùy chọn. Middleware trong file route và đăng ký qua bootstrap/app.php vẫn được hỗ trợ đầy đủ. Các nhóm ưa thích định nghĩa route rõ ràng có thể tiếp tục sử dụng fluent API; các nhóm muốn controller tự mô tả có thể áp dụng attribute.
Terminable Middleware Cho Tác Vụ Sau Response
Terminable middleware thực thi logic sau khi response đã được gửi tới client. Điều này rất hữu ích cho việc ghi log, analytics, hoặc các tác vụ dọn dẹp mà không nên chặn người dùng.
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\Response;
class CollectAnalytics
{
public function handle(Request $request, Closure $next): Response
{
return $next($request); // Pass through without delay
}
public function terminate(Request $request, Response $response): void
{
// Runs after response is sent to client
DB::table('analytics')->insert([
'path' => $request->path(),
'method' => $request->method(),
'status_code' => $response->getStatusCode(),
'user_id' => $request->user()?->id,
'ip' => $request->ip(),
'created_at' => now(),
]);
}
}Phương thức terminate nhận cả request gốc và response cuối cùng. Cần đăng ký middleware này dạng singleton trong AppServiceProvider để đảm bảo cùng một instance xử lý cả handle() và terminate().
Các Pattern Middleware Thực Tế Cho Môi Trường Production
Một số pattern middleware xuất hiện liên tục trong các ứng dụng Laravel ở môi trường production.
Bỏ qua chế độ bảo trì cho phép các IP nội bộ truy cập ứng dụng trong thời gian bảo trì:
class MaintenanceBypass
{
private array $allowedIps = ['192.168.1.0/24', '10.0.0.1'];
public function handle(Request $request, Closure $next): Response
{
if (app()->isDownForMaintenance()) {
foreach ($this->allowedIps as $ip) {
if ($request->ip() === $ip) {
return $next($request);
}
}
}
return $next($request);
}
}Security headers thêm HSTS, content security policy và các header bảo mật khác vào mỗi response:
class SecurityHeaders
{
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
$response->headers->set('X-Content-Type-Options', 'nosniff');
$response->headers->set('X-Frame-Options', 'SAMEORIGIN');
$response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');
$response->headers->set(
'Strict-Transport-Security',
'max-age=31536000; includeSubDomains'
);
return $response;
}
}Các pattern này minh họa hai vị trí middleware chính: trước request (maintenance bypass kiểm tra IP và có thể chặn truy cập) và sau response (security headers thay đổi response trước khi gửi đi).
Sẵn sàng chinh phục phỏng vấn Laravel?
Luyện tập với mô phỏng tương tác, flashcards và bài kiểm tra kỹ thuật.
Nguồn Tham Khảo
- Laravel Middleware Documentation - Tài liệu tham khảo chính thức về đăng ký middleware, group và parameter
- Laravel 13 Release Notes - Thông báo về attribute
#[Middleware]và cải tiếnPreventRequestForgery - Laravel Rate Limiting Documentation - RateLimiter facade, named limiter và cấu hình throttle middleware
Các Pattern Middleware Laravel Cho Chuẩn Bị Phỏng Vấn
- Laravel middleware hoạt động như một pipeline: mỗi class xử lý request, tác động lên nó, rồi chuyển tiếp hoặc cắt ngang bằng một response
- Middleware
authbảo vệ route bằng xác thực dựa trên guard, hỗ trợ nhiều loại người dùng thông qua cú phápauth:guard - Rate limiting thông qua middleware
throttlevà định nghĩaRateLimiter::for()cho phép kiểm soát truy cập phân tầng dựa trên ngữ cảnh người dùng - Custom middleware xử lý các mối quan tâm xuyên suốt như kiểm tra vai trò, làm sạch request và security headers mà không làm rối controller
- Toàn bộ đăng ký middleware diễn ra tại
bootstrap/app.phpsử dụng fluent API, vớiprioritykiểm soát thứ tự thực thi - Attribute
#[Middleware]của Laravel 13 cho phép khai báo middleware trực tiếp trên controller, giữ các quy tắc ủy quyền cùng với handler - Terminable middleware chạy các tác vụ sau response (analytics, logging) mà không ảnh hưởng tới độ trễ phía người dùng
- Tham số middleware qua cú pháp
:paramgiữ cho định nghĩa route rõ ràng và các class middleware có thể tái sử dụng trong nhiều ngữ cảnh khác nhau
Bắt đầu luyện tập!
Kiểm tra kiến thức với mô phỏng phỏng vấn và bài kiểm tra kỹ thuật.
Bạn có tìm ra lỗi trong Laravel không?
Một đoạn mã thật, một lỗi ẩn, mỗi ngày một lượt. Không cần tài khoản để thử.

Viết bởi
Anthony Fillion-MailletNgười sáng lập SharpSkill
Lập trình viên fullstack hơn 10 năm. Anh điều hành SharpSkill và chịu trách nhiệm về mọi nội dung đăng tại đây.
Cập nhật ngày 21 tháng 9, 2026
Thẻ
Chia sẻ
Bài viết liên quan

Câu Hỏi Phỏng Vấn PHP Laravel Developer 2026: Hướng Dẫn Chuẩn Bị Toàn Diện
Hướng dẫn toàn diện để chuẩn bị cho buổi phỏng vấn PHP Laravel developer năm 2026. Bao gồm các câu hỏi kỹ thuật về Eloquent ORM, Service Container, authentication, queue và testing.

Laravel 12 năm 2026: Tính năng mới, Starter Kit và Câu hỏi phỏng vấn
Laravel 12 mang đến các starter kit được thiết kế lại với React 19, Vue 3, Livewire 4 và WorkOS AuthKit. Hướng dẫn đầy đủ về tính năng mới, lộ trình nâng cấp và các câu hỏi phỏng vấn trọng tâm cho năm 2026.

Eloquent ORM: các pattern và tối ưu hoá cho Laravel
Làm chủ Eloquent ORM với các pattern nâng cao và kỹ thuật tối ưu hoá. Eager loading, query scope, accessor, mutator và hiệu năng cho ứng dụng Laravel.