برنامه نویس فان | Fun Developer یک آدم ساده که عاشق برنامه نویسی و کد زدنه :) تلاش میکنه تا به بقیه کمک کنه. توسعه دهنده هسته لاراول و فضای اوپن سورس. فاندر پرانتز و کد نیوز.

میدولور ها (Middlware) چی هستند؟
در لاراول، میدلور (Middleware) یک لایه واسط بین درخواستهای وارد شده به اپلیکیشن و پاسخهایی است که به کاربر بازگردانده میشود. میدلورها به شما اجازه میدهند تا منطق خاصی را قبل از رسیدن درخواست به کنترلر یا بعد از پردازش درخواست در اپلیکیشن اعمال کنید. میدلورها به شما این امکان را میدهند که بدون تغییر در منطق کنترلرها، کنترل دقیقی روی درخواستها و پاسخها داشته باشید. آنها ابزاری قدرتمند برای مدیریت دسترسی، اعتبارسنجی و سایر عملیات قبل یا بعد از پردازش درخواستها هستند.
روش ساخت یک میدلور در لاراول
اولین قدم برای کار با میدولور ها این هست که چطور یک میدولور با استفاده از artisan بسازیم:
php artisan make:middleware NameMiddleware
در اینجا با استفاده از کامند make:middleware
میتونیم یک میدولور جدید بسازیم. تمامی میدلور های ما در پوشه app/Http/Middleware
قرار دارند.
روش رجیستر کردن میدلور ها در لاراول 12
در لاراول قبلا به این شکل بود که ما در فایلی به نام Kernel.php
میدلور های خودمون رو ثبت میکردیم. اما الان با استفاده از فایل app.php
که در پوشه bootstrap
هست میایم اینکار رو انجام میدیم:
use App\Http\Middleware\IsAdmin;
->withMiddleware(function (Middleware $middleware) {
$middleware->append(IsAdmin::class);
})
در اینجا میبینید که ما به صورت همگانی (Global) یک میدلور به تمامی روت ها اضافه کردیم اما شاید بخوایم روی یک سری گروها و ... اضافه کنیم، اون وقت چی؟
use App\Http\Middleware\IsAdmin;
use App\Http\Middleware\IsOwner;
->withMiddleware(function (Middleware $middleware) {
$middleware->appendToGroup('group-name', [
IsAdmin::class,
]);
$middleware->prependToGroup('group-name', [
IsOwner::class,
]);
})
حالا به سادگی این کار انجام دادیم. شما میتونید به گروه هایی مثل web
یا api
هم چندین میدلور دلخواه اضافه کنید.
اضافه کردن یک میدلور به یک روت در لاراول
گاهی شما نیاز دارید که یک میدلور دلخواه به یک روت اضافه کنید، برای اینکار کافیه به سادگی از متد "()middleware
" در روتینگ استفاده کنید:
use App\Http\Middleware\IsAdmin;
Route::get('/admin', function () {
// ...
})->middleware(IsAdmin::class);
همینطور میتونید چندین میدلور به یک روت اضافه کنید:
Route::get('/', function () {
// ...
})->middleware([IsAdmin::class, IsOwner::class]);
Middleware Aliases
در خیلی از مواقع شما نیاز دارید برای میدلور هاتون یک نام درست کنید که با استفاده از اون نام در بخش های اپلیکیشتون ازش استفاده کنید. لاراول این کارو برای ما انجام داده:
use App\Http\Middleware\IsAdmin;
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'admin' => IsAdmin::class
]);
})
در اینجا میبینید که ما برای میدلور IsAdmin
یک نام مستعار به نام "admin
" درست کردیم. در بقیه جاهای اپلیکیشن شما میتونید از این اسم استفاده کنید به جای استفاده از خوده کلاس:
Route::get('/admin', function () {
// ...
})->middleware('admin');
در اینجا میبینید که ما از اسم admin استفاده کردیم به جای استفاده از کلاس میدلور.
جدول میدولور های هسته لاراول با اسم مستعار
در اینجا شما جدول تمامی میدلور های لاراول با اسم مستعار اون ها رو در دست دارید:
Illuminate\Auth\Middleware\Authenticate |
auth |
Illuminate\Auth\Middleware\AuthenticateWithBasicAuth |
auth.basic |
Illuminate\Session\Middleware\AuthenticateSession |
auth.session |
Illuminate\Http\Middleware\SetCacheHeaders |
cache.headers |
Illuminate\Auth\Middleware\Authorize |
can |
Illuminate\Auth\Middleware\RedirectIfAuthenticated |
guest |
Illuminate\Auth\Middleware\RequirePassword |
password.confirm |
Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests |
precognitive |
Illuminate\Routing\Middleware\ValidateSignature |
signed |
Spark\Http\Middleware\VerifyBillableIsSubscribed |
subscribed |
Illuminate\Routing\Middleware\ThrottleRequests |
throttle |
Illuminate\Auth\Middleware\EnsureEmailIsVerified |
verified |
اولویت بندی میدلور ها
در لاراول اگه شما نیاز دارید که میدلور ها براساس یک الویت اجرا بشن، میتونید با استفاده از متد "()priority
" این کار انجام بدید:
->withMiddleware(function (Middleware $middleware) {
$middleware->priority([
Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
Illuminate\Cookie\Middleware\EncryptCookies::class,
Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
Illuminate\Session\Middleware\StartSession::class,
Illuminate\View\Middleware\ShareErrorsFromSession::class,
Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
Illuminate\Routing\Middleware\ThrottleRequests::class,
Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class,
Illuminate\Routing\Middleware\SubstituteBindings::class,
Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class,
Illuminate\Auth\Middleware\Authorize::class,
]);
})
پارامتر ها در میدلور
پیش اومده که شما در میدلور نیاز به ارسال پارامتر خاصی دارید و حتی میتونید با این پارامتر ها یک میدلور درست کنید و در بخش های مختلف براساس پارامتر اون کار انجام بدید، مثل چک کردن دسترسی کاربر! لاراول این کار هم برای ما پیاده سازی کرده و به راحتی این کار میتونیم انجام بدیم:
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\Http\Foundation\Response;
class EnsureUserHasRole
{
/**
* Handle an incoming request.
*
* @param Closure(Illuminate\Http\Request): (Symfony\Component\Http\Foundation\Response) $next
*/
public function handle(Request $request, Closure $next, string $role): Response
{
if (! $request->user()->hasRole($role)) {
// Redirect...
}
return $next($request);
}
}
در اینجا شما یک پارامتر مشخص کردید به نام role و زمانی که از این میدلور استفاده میکنید، میتونید پارامتر role ارسال کنید:
use App\Http\Middleware\EnsureUserHasRole;
Route::put('/post/{id}', function (string $id) {
// ...
})->middleware(EnsureUserHasRole::class.':editor');
Terminable Middleware
یک نکته هسته ای از لاراول! آخرین مرحله از Lifecycle لاراول، میدلور های Terminable اجرا میشن. اگه متد "()terminate
" در میدلورتون باشه و وب سرورتون از FastCGI استفاده کنید، متد ()terminate
به صورت اتوماتیک بعد از ارسال response اجرا میشه:
namespace Illuminate\Session\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\Http\Foundation\Response;
class TerminatingMiddleware
{
/**
* Handle an incoming request.
*
* @param Closure(Illuminate\Http\Request): (Symfony\Component\Http\Foundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
return $next($request);
}
/**
* Handle tasks after the response has been sent to the browser.
*/
public function terminate(Request $request, Response $response): void
{
// ...
}
}
اولین نفر باش که نظر ثبت میکنی :) یعنی یه کامنت به ما نمیرسه 😁