آموزش کار با میدلور ها (Middleware) در لاراول

میدولور ها (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
    {
        // ...
    }
}


0 🔥
0 🎉
0 😮
0 👍
1 💜
0 👏
میلاد خسروی
نویسنده کد نیوز

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

0+ نظر

برای ثبت نظر ابتدا ورود کنید.

0 نظر

    اولین نفر باش که نظر ثبت میکنی :) یعنی یه کامنت به ما نمیرسه 😁