در یک برنامه Laravel، هر Request که از طرف کاربر وارد میشود نباید لزوماً مستقیماً به Controller برسد.
گاهی لازم است قبل از اجرای Controller بررسی کنیم که:
- آیا کاربر وارد حساب کاربری شده است؟
- آیا کاربر اجازه انجام این عملیات را دارد؟
- آیا درخواست شرایط لازم را دارد؟
- آیا یک Header خاص وجود دارد؟
- آیا کاربر از محدوده مشخصی اجازه دسترسی دارد؟
- آیا درخواست باید قبل از رسیدن به Controller فیلتر شود؟
برای انجام چنین کارهایی در Laravel از مفهومی به نام Middleware استفاده میشود.
Middleware یکی از اجزای مهم چرخه پردازش Request در Laravel است و میتواند قبل از رسیدن درخواست به بخش اصلی برنامه، آن را بررسی یا تغییر دهد.
در این مقاله ابتدا میبینیم Middleware در Laravel چیست، سپس با نحوه ساخت Middleware، اتصال آن به Route و Controller، Middlewareهای گروهی، ارسال پارامتر و چند مثال واقعی آشنا میشویم.
# Middleware در Laravel چیست؟
Middleware را میتوان یک لایه واسط بین Request ورودی و برنامه در نظر گرفت.
به زبان ساده، Middleware میتواند قبل از اینکه Request به Controller برسد، آن را بررسی کند.
یک جریان ساده را تصور کنید:
کاربر
↓
Request
↓
Middleware
↓
Controller
↓
Response
↓
کاربر
مثلاً فرض کنید یک صفحه فقط برای کاربران واردشده قابل دسترسی است.
در این حالت Middleware میتواند بررسی کند:
آیا کاربر Login کرده است؟
↓
بله → ادامه به Controller
↓
خیر → انتقال به صفحه Login
بنابراین Middleware مانند یک فیلتر یا دروازه در مسیر Request عمل میکند.
# چرا به Middleware نیاز داریم؟
فرض کنید یک سایت داریم که ۲۰ صفحه آن فقط برای کاربران واردشده قابل مشاهده است.
اگر برای هر Controller به صورت جداگانه بنویسیم:
if (!auth()->check()) {
return redirect()->route('login');
}
کد بهسرعت تکراری و سخت برای نگهداری میشود.
بهتر است این منطق را یک بار در Middleware قرار دهیم و سپس آن Middleware را روی Routeهای مورد نیاز اعمال کنیم.
مثلاً:
Middleware: auth
و سپس:
Route::middleware('auth')->group(function () {
// صفحات خصوصی
});
در این حالت Laravel قبل از اجرای Routeهای داخل گروه، Middleware مربوطه را اجرا میکند.
# Middleware در معماری Laravel کجای کار قرار میگیرد؟
برای درک بهتر Middleware، بهتر است مسیر کلی یک Request را ببینیم:
Browser
↓
HTTP Request
↓
Laravel
↓
Middleware
↓
Route
↓
Controller
↓
Model / Service
↓
Response
↓
Middleware
↓
Browser
نکته مهم این است که Middleware فقط برای قبل از اجرای Controller نیست.
Middleware میتواند بعد از اجرای بخش اصلی برنامه نیز در مسیر بازگشت Response نقش داشته باشد.
به همین دلیل Middleware را میتوان یک لایه در اطراف جریان پردازش Request/Response در نظر گرفت.
# Middleware چه کارهایی میتواند انجام دهد؟
کاربرد Middleware بسیار گسترده است.
برای مثال میتوان از Middleware برای موارد زیر استفاده کرد:
احراز هویت
بررسی اینکه کاربر وارد حساب خود شده یا خیر.
کنترل دسترسی
بررسی اینکه کاربر اجازه دسترسی به یک بخش را دارد یا خیر.
بررسی Header
مثلاً بررسی وجود یک Header مشخص در API.
محدود کردن دسترسی
برای مثال محدود کردن دسترسی یک مسیر به کاربران خاص.
ثبت اطلاعات Request
میتوان اطلاعات خاصی از درخواست را برای Logging بررسی کرد.
تغییر Request
در شرایط خاص میتوان اطلاعات Request را قبل از رسیدن به Controller پردازش کرد.
تغییر Response
Middleware میتواند هنگام برگشت Response نیز در فرآیند پردازش نقش داشته باشد.
# Middlewareهای آماده Laravel
Laravel تعدادی Middleware کاربردی دارد که در پروژههای مختلف از آنها استفاده میشود.
یکی از شناختهشدهترین آنها:
auth
است.
مثلاً:
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware('auth');
در این حالت Route به Middleware احراز هویت متصل شده است.
اگر کاربر شرایط لازم برای عبور از Middleware را نداشته باشد، جریان به Controller یا Closure نهایی نمیرسد.
# Middleware را کجا پیدا کنیم؟
Middlewareهای پروژه Laravel در ساختار برنامه در بخش HTTP قرار میگیرند.
در ساختارهای رایج Laravel، Middlewareهای سفارشی را در مسیر:
app/Http/Middleware
مشاهده میکنید.
مثلاً:
app/
└── Http/
└── Middleware/
├── CheckUserStatus.php
└── AdminMiddleware.php
نام و نحوه ثبت Middleware بسته به ساختار و نسخه Laravel میتواند متفاوت باشد، اما مفهوم اصلی یکسان است: Middleware یک لایه قابل استفاده برای فیلتر و پردازش Request/Response است.
# ساخت Middleware در Laravel
برای ساخت Middleware میتوانیم از Artisan استفاده کنیم.
دستور:
php artisan make:middleware CheckUserStatus
بعد از اجرای دستور، Laravel یک Middleware جدید ایجاد میکند.
معمولاً فایل آن در مسیر زیر قرار میگیرد:
app/Http/Middleware/CheckUserStatus.php
یک Middleware ساده میتواند ساختاری مشابه این داشته باشد:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class CheckUserStatus
{
public function handle(Request $request, Closure $next): Response
{
return $next($request);
}
}
قسمت مهم این کد:
return $next($request);
است.
این دستور یعنی:
> Request را به مرحله بعدی جریان پردازش ارسال کن.
اگر Middleware به این مرحله نرسد، میتواند Request را متوقف کند.
# $next در Middleware چیست؟
در Middleware معمولاً متغیری مانند:
$next
میبینیم.
این متغیر نماینده مرحله بعدی پردازش Request است.
بنابراین:
return $next($request);
یعنی Request را به مرحله بعدی بفرست.
اگر Middleware قبل از Controller قرار گرفته باشد، مرحله بعدی میتواند Middleware دیگری یا در نهایت Controller باشد.
# جلوگیری از ادامه Request در Middleware
یکی از قابلیتهای مهم Middleware این است که میتواند جلوی ادامه Request را بگیرد.
مثلاً:
public function handle(Request $request, Closure $next): Response
{
if (!$request->user()) {
return redirect()->route('login');
}
return $next($request);
}
اگر کاربر وارد حساب نشده باشد:
return redirect()->route('login');
اجرا میشود و Request دیگر به Controller اصلی نمیرسد.
اما اگر کاربر احراز هویت شده باشد:
return $next($request);
اجرا میشود.
# یک مثال واقعی: Middleware بررسی وضعیت کاربر
فرض کنید در یک سایت کاربران ممکن است فعال یا غیرفعال باشند.
میخواهیم کاربر غیرفعال نتواند وارد بخش خصوصی سایت شود.
میتوانیم Middleware بسازیم:
php artisan make:middleware CheckUserStatus
سپس:
public function handle(Request $request, Closure $next): Response
{
$user = $request->user();
if ($user && !$user->is_active) {
auth()->logout();
return redirect()
->route('login')
->with('error', 'حساب کاربری شما غیرفعال است.');
}
return $next($request);
}
حالا Middleware میتواند روی Routeهای خاص اعمال شود.
# اتصال Middleware به Route
یکی از سادهترین روشهای استفاده از Middleware، اتصال آن به Route است.
مثلاً:
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware('auth');
در اینجا Middleware:
auth
به Route متصل شده است.
# اتصال Middleware به چند Route
اگر چند Route به یک Middleware نیاز داشته باشند، میتوانیم آنها را در یک گروه قرار دهیم.
مثلاً:
Route::middleware('auth')->group(function () {
Route::get('/dashboard', function () {
return view('dashboard');
});
Route::get('/profile', function () {
return view('profile');
});
Route::get('/settings', function () {
return view('settings');
});
});
حالا تمام Routeهای داخل این گروه تحت Middleware قرار گرفتهاند.
این روش بسیار بهتر از تکرار کردن:
->middleware('auth')
برای تعداد زیادی Route است.
# استفاده از چند Middleware برای یک Route
یک Route میتواند چند Middleware داشته باشد.
مثلاً:
Route::get('/admin', function () {
return view('admin.dashboard');
})->middleware([
'auth',
'admin',
]);
در این حالت Request باید از Middlewareهای تعیینشده عبور کند.
برای پروژههایی که چند سطح کنترل دسترسی دارند، چنین ساختاری بسیار کاربردی است.
# Middleware در Controller
Middleware را میتوان در سطح Controller نیز استفاده کرد.
برای مثال میتوان Middleware مشخصی را برای Controller اعمال کرد.
ایده اصلی این است که به جای اینکه تکتک Routeها را مدیریت کنیم، Middleware را به Controller یا بخشی از Controller مرتبط کنیم.
این روش مخصوصاً در Controllerهای بزرگتر یا Resourceهای مشخص میتواند مفید باشد.
# Middleware برای چه Routeهایی مناسب است؟
فرض کنید یک فروشگاه داریم:
/
/products
/products/{product}
/account
/orders
/wallet
/tickets
/admin
صفحات عمومی:
/
/products
/products/{product}
نیازی به احراز هویت ندارند.
اما:
/account
/orders
/wallet
/tickets
صفحات خصوصی هستند.
بنابراین میتوانیم بنویسیم:
Route::middleware('auth')->group(function () {
Route::get('/account', ...);
Route::get('/orders', ...);
Route::get('/wallet', ...);
Route::get('/tickets', ...);
});
این ساختار بسیار تمیزتر از بررسی Login بودن کاربر در تکتک Controllerها است.
# Middleware گروهی چیست؟
گاهی چند Middleware باید به صورت یک مجموعه روی Routeهای مختلف اعمال شوند.
برای مثال یک گروه میتواند شامل Middlewareهای مختلف باشد:
auth
verified
...
در چنین شرایطی گروه Middleware کمک میکند چند Middleware به صورت یک مجموعه مدیریت شوند.
در Laravel گروههایی برای کاربردهای رایج نیز وجود دارند و میتوان Middlewareهای مناسب را بر اساس معماری پروژه در مسیرهای مورد نیاز قرار داد.
# Middleware با پارامتر
گاهی یک Middleware باید رفتار متفاوتی بر اساس یک مقدار داشته باشد.
مثلاً میخواهیم Middleware بررسی کند کاربر چه Roleای دارد.
ممکن است بخواهیم چیزی شبیه این داشته باشیم:
->middleware('role:admin')
یا:
->middleware('role:editor')
در این حالت Middleware میتواند پارامتر دریافت کند.
یک ساختار مفهومی برای Middleware:
public function handle(
Request $request,
Closure $next,
string $role
): Response {
// بررسی Role
return $next($request);
}
در این مثال:
$role
مقداری است که هنگام اتصال Middleware به Route ارسال شده است.
# مثال Middleware برای Role
فرض کنیم کاربران سیستم سه Role دارند:
admin
editor
user
میخواهیم فقط مدیر به یک Route دسترسی داشته باشد.
میتوانیم Middlewareای داشته باشیم که Role مورد انتظار را دریافت کند.
مثلاً:
Route::get('/admin/dashboard', function () {
return view('admin.dashboard');
})->middleware('role:admin');
در اینجا:
role:admin
یعنی Middleware باید Role مورد انتظار را بررسی کند.
البته در پروژههای واقعی میتوان برای مدیریت Role و Permission از معماریهای استاندارد و پکیجهای تخصصی نیز استفاده کرد.
# Middleware و Authentication
یکی از مهمترین کاربردهای Middleware در Laravel، احراز هویت است.
مثلاً:
Route::middleware('auth')->group(function () {
Route::get('/dashboard', ...);
});
این ساختار میگوید مسیر مورد نظر فقط برای کاربران احراز هویتشده در دسترس باشد.
نکته مهم این است که Authentication و Authorization دو مفهوم متفاوت هستند.
Authentication:
> آیا این کاربر واقعاً وارد حساب خودش شده است؟
Authorization:
> آیا این کاربر اجازه انجام این عملیات را دارد؟
Middleware میتواند در هر دو سناریو نقش داشته باشد، اما طراحی دقیق سیستم دسترسی باید بر اساس معماری پروژه انجام شود.
# Middleware و Authorization
فرض کنید کاربر وارد حساب شده است، اما فقط مدیران باید بتوانند وارد پنل مدیریت شوند.
در اینجا صرفاً:
auth
کافی نیست.
ممکن است به یک بررسی سطح دسترسی نیز نیاز داشته باشیم.
مثلاً:
Request
↓
auth
↓
admin
↓
Controller
در چنین ساختاری ابتدا ورود کاربر بررسی میشود و سپس سطح دسترسی او.
# Middleware قبل و بعد از Request
یک Middleware میتواند قبل از ادامه Request کاری انجام دهد:
public function handle(Request $request, Closure $next): Response
{
// قبل از ادامه Request
return $next($request);
}
اما میتوان Response برگشتی را نیز دریافت و پردازش کرد:
public function handle(Request $request, Closure $next): Response
{
// قبل از Controller
$response = $next($request);
// بعد از Controller
return $response;
}
این الگو زمانی مفید است که Middleware باید در زمان برگشت Response نیز کاری انجام دهد.
# Middleware و Request چیست؟
Middleware مستقیماً با مفهوم HTTP Request در ارتباط است.
مثلاً میتوان اطلاعاتی مانند Method درخواست را بررسی کرد:
$request->method()
یا URL را بررسی کرد:
$request->url()
یا اطلاعات کاربر احراز هویتشده را دریافت کرد:
$request->user()
بنابراین Middleware یکی از جاهایی است که میتوان قبل از اجرای Controller اطلاعات Request را بررسی کرد.
در مقاله بعدی این موضوع را به صورت عمیقتر بررسی خواهیم کرد و به سراغ Request و Response در Laravel میرویم.
# Middleware و API
Middleware فقط برای صفحات HTML نیست.
در APIها نیز Middleware کاربرد بسیار زیادی دارد.
برای مثال میتوان Middlewareهایی برای:
- Authentication
- بررسی Token
- Rate Limiting
- بررسی Header
- ثبت درخواستها
- کنترل دسترسی
- بررسی شرایط خاص API
استفاده کرد.
مثلاً:
API Request
↓
Authentication Middleware
↓
Authorization Middleware
↓
Controller
↓
JSON Response
این ساختار در APIهای واقعی بسیار متداول است.
# Middleware برای محدود کردن دسترسی به پنل مدیریت
یکی از مثالهای رایج در پروژههای واقعی، پنل مدیریت است.
فرض کنید:
/admin
/admin/users
/admin/orders
/admin/settings
فقط مدیران باید بتوانند به این قسمت دسترسی داشته باشند.
میتوانیم Routeها را گروهبندی کنیم:
Route::prefix('admin')
->middleware(['auth', 'admin'])
->group(function () {
Route::get('/dashboard', ...);
Route::get('/users', ...);
Route::get('/orders', ...);
Route::get('/settings', ...);
});
در اینجا دو لایه بررسی داریم:
auth
↓
آیا کاربر وارد شده؟
admin
↓
آیا کاربر مدیر است؟
↓
Controller
# Middleware و Prefix چه تفاوتی دارند؟
گاهی این مفاهیم با هم اشتباه گرفته میشوند.
مثلاً:
Route::prefix('admin')
->middleware('auth')
->group(function () {
...
});
prefix مسیر URL را مدیریت میکند.
مثلاً:
/admin/users
/admin/orders
اما:
middleware('auth')
شرایط دسترسی به Route را کنترل میکند.
بنابراین:
prefix → ساختار URL
middleware → فیلتر و کنترل جریان Request
# Middleware و Controller چه تفاوتی دارند؟
این دو نیز نقش متفاوتی دارند.
Middleware
قبل یا در اطراف اجرای درخواست، شرایط و دسترسی را بررسی میکند.
Controller
منطق مربوط به مدیریت یک درخواست و تولید Response را بر عهده میگیرد.
برای مثال:
Request
↓
Middleware
↓
Controller
↓
Response
مثلاً Middleware بررسی میکند:
کاربر وارد شده؟
و Controller کار اصلی را انجام میدهد:
اطلاعات سفارش را دریافت کن
↓
آن را پردازش کن
↓
View یا JSON برگردان
# Middleware و Service چه تفاوتی دارند؟
Service معمولاً برای قرار دادن منطق قابل استفاده مجدد و منطق کسبوکار استفاده میشود.
Middleware برای کنترل و پردازش جریان Request مناسب است.
مثلاً:
Middleware
→ آیا کاربر اجازه ورود دارد؟
Controller
→ درخواست را مدیریت کن
Service
→ عملیات کسبوکار را انجام بده
این تفکیک مسئولیت باعث میشود معماری پروژه تمیزتر شود.
# Middleware را بیش از حد استفاده نکنیم
Middleware بسیار قدرتمند است، اما نباید تمام منطق برنامه را داخل آن قرار دهیم.
مثلاً اگر Middleware شامل صدها خط کد مربوط به محاسبه قیمت، ثبت سفارش، محاسبه کمیسیون و پردازش پرداخت باشد، احتمالاً مسئولیتهای زیادی به آن داده شده است.
بهتر است Middleware روی کار اصلی خود تمرکز کند:
> فیلتر، بررسی و کنترل جریان Request/Response.
# مثال کامل؛ محافظت از صفحه کیف پول
فرض کنید یک سیستم فروشگاهی داریم و صفحه کیف پول باید فقط برای کاربران واردشده قابل مشاهده باشد.
Route:
Route::get('/wallet', function () {
return view('wallet.index');
})->middleware('auth');
جریان درخواست:
کاربر
↓
/wallet
↓
auth Middleware
↓
آیا کاربر وارد شده؟
↓
├── خیر → Login
│
└── بله
↓
wallet Controller / Route
↓
Wallet View
این نمونه ساده نشان میدهد Middleware چطور یک لایه امنیتی و کنترلی بین Request و بخش اصلی برنامه ایجاد میکند.
# چگونه Middlewareهای پروژه را بررسی کنیم؟
هنگام کار روی پروژههای Laravel ممکن است بخواهید بدانید یک Route چه Middlewareهایی دارد.
یکی از ابزارهای کاربردی Artisan:
php artisan route:list
است.
این دستور اطلاعات Routeهای پروژه را نمایش میدهد و در بررسی Middlewareهای متصل به Routeها نیز بسیار مفید است.
اگر پروژه بزرگی دارید، route:list یکی از ابزارهای مهم برای عیبیابی مسیرها و Middlewareها محسوب میشود.
# خطاهای رایج در Middleware
۱. Middleware ساخته شده اما استفاده نشده است
ممکن است Middleware را ایجاد کرده باشید ولی آن را به Route، Controller یا گروه مربوطه متصل نکرده باشید.
در این حالت Middleware عملاً در مسیر درخواست قرار نمیگیرد.
۲. فراموش کردن $next
اگر Middleware باید اجازه ادامه Request را بدهد اما این کار انجام نشود، جریان درخواست متوقف میشود.
مثلاً:
public function handle(Request $request, Closure $next): Response
{
// ...
}
اگر در شرایط لازم:
return $next($request);
را برنگردانید، Request ممکن است به مرحله بعد نرسد.
۳. قرار دادن منطق بیش از حد در Middleware
Middleware نباید تبدیل به یک Controller یا Service مخفی شود.
اگر منطق زیادی داخل آن جمع شده است، بهتر است مسئولیتها را جدا کنیم.
۴. اشتباه گرفتن Authentication و Authorization
این دو مفهوم یکی نیستند.
Authentication
= چه کسی هستی؟
Authorization
= اجازه انجام چه کاری را داری؟
در طراحی Middleware باید این تفاوت را در نظر گرفت.
۵. فراموش کردن ترتیب Middlewareها
وقتی چند Middleware روی یک Route قرار میگیرند، ترتیب پردازش آنها میتواند روی رفتار برنامه تأثیر داشته باشد.
بنابراین در پروژههای پیچیده باید زنجیره Middlewareها را بهدرستی طراحی و بررسی کرد.
# بهترین روشهای استفاده از Middleware در Laravel
برای داشتن معماری تمیز، چند نکته مهم را رعایت کنید.
۱. هر Middleware یک مسئولیت مشخص داشته باشد
مثلاً:
CheckUserStatus
برای بررسی وضعیت کاربر باشد، نه اینکه همزمان پرداخت و سفارش را نیز مدیریت کند.
۲. منطق تجاری را جدا نگه دارید
Middleware محل مناسبی برای تمام Business Logic برنامه نیست.
۳. Middlewareهای قابل استفاده مجدد بسازید
اگر یک منطق در چند بخش برنامه استفاده میشود، Middleware میتواند از تکرار آن جلوگیری کند.
۴. از Middleware برای کنترل جریان Request استفاده کنید
Middleware زمانی بیشترین ارزش را دارد که واقعاً در مسیر Request/Response قرار گرفته و مسئولیت مشخصی داشته باشد.
۵. برای Routeهای مشابه از Group استفاده کنید
به جای:
Route::get(...)->middleware('auth');
Route::get(...)->middleware('auth');
Route::get(...)->middleware('auth');
میتوان از:
Route::middleware('auth')->group(function () {
// routes
});
استفاده کرد.
# جمعبندی
Middleware در Laravel یکی از مهمترین ابزارها برای کنترل و فیلتر کردن Request و Response است.
Middleware میتواند قبل از رسیدن درخواست به Controller، شرایط مختلفی را بررسی کند و در صورت مناسب بودن شرایط، درخواست را به مرحله بعد بفرستد.
مهمترین کاربردهای Middleware عبارتاند از:
- Authentication
- Authorization
- کنترل دسترسی
- بررسی وضعیت کاربر
- بررسی Request
- پردازش Headerها
- کنترل API
- ثبت اطلاعات درخواست
- محدود کردن دسترسی Routeها
- پردازش Response
ساختار ساده آن را میتوان اینگونه خلاصه کرد:
Request
↓
Middleware
↓
Controller
↓
Response
و در پروژههای واقعی ممکن است چند Middleware پشت سر هم قرار بگیرند:
Request
↓
Authentication
↓
Authorization
↓
Custom Middleware
↓
Controller
↓
Service
↓
Response
درک Middleware برای توسعه پروژههای واقعی Laravel بسیار مهم است، چون با بزرگتر شدن پروژه، کنترل دسترسی و مدیریت جریان Request اهمیت بیشتری پیدا میکند.
# سوالات متداول Middleware در Laravel
Middleware در Laravel چیست؟
Middleware یک لایه در مسیر پردازش Request و Response است که میتواند قبل یا بعد از بخش اصلی پردازش درخواست، اطلاعات را بررسی یا پردازش کند.
Middleware چه کاربردی دارد؟
از Middleware برای Authentication، Authorization، کنترل دسترسی، بررسی Request، کنترل API، بررسی Header و بسیاری از وظایف مرتبط با جریان درخواست استفاده میشود.
چگونه در Laravel یک Middleware بسازیم؟
میتوان از Artisan استفاده کرد:
php artisan make:middleware CheckUserStatus
چگونه Middleware را به Route متصل کنیم؟
برای یک Route میتوان از ساختاری مانند زیر استفاده کرد:
Route::get('/dashboard', ...)
->middleware('auth');
آیا یک Route میتواند چند Middleware داشته باشد؟
بله. میتوان چند Middleware را به یک Route یا گروهی از Routeها متصل کرد.
تفاوت Middleware و Controller چیست؟
Middleware برای کنترل و فیلتر جریان Request/Response استفاده میشود، در حالی که Controller مسئول مدیریت عملیات مربوط به درخواست و تولید Response است.
آیا Middleware فقط برای احراز هویت است؟
خیر. احراز هویت یکی از کاربردهای مهم Middleware است، اما Middleware میتواند برای کنترل دسترسی، بررسی Request، API، Headerها، Logging و موارد دیگر نیز استفاده شود.
آیا Middleware میتواند Request را متوقف کند؟
بله. Middleware میتواند به جای ارسال Request به مرحله بعد، Response یا Redirect برگرداند و در نتیجه ادامه جریان را متوقف کند.





