نسخه:

میان افزار

معرفی

Middleware مکانیزمی مناسب برای فیلتر کردن درخواست‌های HTTP که وارد برنامه شما می‌شوند، فراهم می‌کند. به عنوان مثال، لاراول شامل یک میان افزار است که تأیید می کند کاربر برنامه شما احراز هویت شده است. اگر کاربر احراز هویت نشود، میان افزار کاربر را به صفحه ورود هدایت می کند. با این حال، اگر کاربر احراز هویت شود، میان‌افزار به درخواست اجازه می‌دهد تا در برنامه ادامه یابد.

میان‌افزار اضافی را می‌توان برای انجام کارهای مختلف علاوه بر احراز هویت نوشت. یک میان افزار CORS ممکن است مسئول اضافه کردن هدرهای مناسب به تمام پاسخ هایی باشد که برنامه شما را ترک می کنند. یک میان‌افزار ثبت‌نام ممکن است تمام درخواست‌های دریافتی را به برنامه شما ثبت کند.

چندین میان افزار در چارچوب لاراول گنجانده شده است، از جمله میان افزار برای احراز هویت و حفاظت CSRF. همه این میان افزارها در app/Http/Middleware دایرکتوری قرار دارند.

تعریف میان افزار

برای ایجاد یک میان افزار جدید، از make:middleware دستور Artisan استفاده کنید:

php artisan make:middleware CheckAge

CheckAge این دستور یک کلاس جدید را در دایرکتوری شما قرار می دهد app/Http/Middleware . در این میان افزار، ما فقط در صورتی اجازه دسترسی به مسیر را می دهیم که مقدار ارائه شده age بیشتر از 200 باشد. در غیر این صورت، کاربران را به URI هدایت می کنیم home :

<?php
 
namespace App\Http\Middleware;
 
use Closure;
 
class CheckAge
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($request->age <= 200) {
return redirect('home');
}
 
return $next($request);
}
}

همانطور که می بینید، اگر مقدار داده شده age کمتر یا مساوی باشد 200 ، میان افزار یک تغییر مسیر HTTP را به مشتری برمی گرداند. در غیر این صورت، درخواست بیشتر به برنامه ارسال می شود. برای ارسال درخواست عمیق‌تر به برنامه (اجازه دادن به میان‌افزار برای "عبور")، پاسخ $next تماس را با $request .

بهتر است میان‌افزار را به‌عنوان یک سری از درخواست‌های HTTP «لایه‌ها» تصور کنید که قبل از ورود به برنامه شما باید از آن عبور کنند. هر لایه می تواند درخواست را بررسی کند و حتی آن را به طور کامل رد کند.

همه میان‌افزارها از طریق کانتینر سرویس حل می‌شوند ، بنابراین می‌توانید وابستگی‌هایی را که در سازنده میان‌افزار نیاز دارید تایپ کنید.

قبل و بعد از میان افزار

اینکه یک میان افزار قبل یا بعد از درخواست اجرا شود به خود میان افزار بستگی دارد. به عنوان مثال، میان افزار زیر برخی از وظایف را قبل از رسیدگی به درخواست توسط برنامه انجام می دهد:

<?php
 
namespace App\Http\Middleware;
 
use Closure;
 
class BeforeMiddleware
{
public function handle($request, Closure $next)
{
// Perform action
 
return $next($request);
}
}

با این حال، این میان افزار پس از رسیدگی به درخواست توسط برنامه، وظیفه خود را انجام می دهد:

<?php
 
namespace App\Http\Middleware;
 
use Closure;
 
class AfterMiddleware
{
public function handle($request, Closure $next)
{
$response = $next($request);
 
// Perform action
 
return $response;
}
}

ثبت نرم افزار میانی

میان افزار جهانی

اگر می خواهید یک میان افزار در طول هر درخواست HTTP برای برنامه شما اجرا شود، کلاس میان افزار را در $middleware ویژگی کلاس خود فهرست کنید app/Http/Kernel.php .

اختصاص نرم افزار میانی به مسیرها

اگر می خواهید میان افزار را به مسیرهای خاصی اختصاص دهید، ابتدا باید میان افزار را یک کلید در app/Http/Kernel.php فایل خود اختصاص دهید. به طور پیش فرض، $routeMiddleware ویژگی این کلاس حاوی ورودی هایی برای میان افزار موجود در لاراول است. برای اضافه کردن خود، آن را به این لیست اضافه کنید و کلید دلخواه خود را به آن اختصاص دهید:

// Within App\Http\Kernel Class...
 
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];

هنگامی که میان‌افزار در هسته HTTP تعریف شد، می‌توانید از این middleware روش برای اختصاص میان‌افزار به یک مسیر استفاده کنید:

Route::get('admin/profile', function () {
//
})->middleware('auth');

همچنین می توانید چند میان افزار را به مسیر اختصاص دهید:

Route::get('/', function () {
//
})->middleware('first', 'second');

هنگام تخصیص میان‌افزار، می‌توانید نام کلاس کاملاً واجد شرایط را نیز ارسال کنید:

use App\Http\Middleware\CheckAge;
 
Route::get('admin/profile', function () {
//
})->middleware(CheckAge::class);

گروه های میان افزار

گاهی اوقات ممکن است بخواهید چندین میان افزار را زیر یک کلید گروه بندی کنید تا تخصیص آنها به مسیرها آسان تر شود. می توانید این کار را با استفاده از $middlewareGroups ویژگی هسته HTTP خود انجام دهید.

خارج از جعبه، لاراول با گروه‌های میان‌افزاری همراه می‌شود web که api حاوی میان‌افزار معمولی هستند که ممکن است بخواهید در مسیرهای رابط کاربری وب و API خود اعمال کنید:

/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
 
'api' => [
'throttle:60,1',
'auth:api',
],
];

گروه‌های میان‌افزار ممکن است به مسیرها و کنش‌های کنترل‌کننده با استفاده از نحو مشابه میان‌افزار منفرد اختصاص داده شوند. مجدداً، گروه‌های میان‌افزار تخصیص بسیاری از میان‌افزارها به یک مسیر را به طور همزمان راحت‌تر می‌کنند:

Route::get('/', function () {
//
})->middleware('web');
 
Route::group(['middleware' => ['web']], function () {
//
});
 
Route::middleware(['web', 'subscribed'])->group(function () {
//
});

خارج از جعبه، گروه میان افزار به طور خودکار به فایل web شما اعمال می شود . routes/web.php RouteServiceProvider

مرتب سازی میان افزارها

به ندرت، ممکن است نیاز داشته باشید که میان افزار خود را با یک ترتیب خاص اجرا کنید، اما زمانی که به مسیر اختصاص داده می شود، کنترلی بر ترتیب آنها نداشته باشید. در این مورد، می توانید اولویت میان افزار خود را با استفاده از $middlewarePriority ویژگی فایل خود مشخص کنید app/Http/Kernel.php :

/**
* The priority-sorted list of middleware.
*
* This forces non-global middleware to always be in the given order.
*
* @var array
*/
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\Authenticate::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];

پارامترهای میان افزار

میان افزار همچنین می تواند پارامترهای اضافی را دریافت کند. به عنوان مثال، اگر برنامه شما باید قبل از انجام یک عمل مشخص، تأیید کند که کاربر تأیید شده دارای یک "نقش" است، می توانید یک CheckRole میان افزار ایجاد کنید که یک نام نقش را به عنوان یک آرگومان اضافی دریافت کند.

پارامترهای میان‌افزار اضافی پس از آرگومان به میان‌افزار ارسال می‌شوند $next :

<?php
 
namespace App\Http\Middleware;
 
use Closure;
 
class CheckRole
{
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string $role
* @return mixed
*/
public function handle($request, Closure $next, $role)
{
if (! $request->user()->hasRole($role)) {
// Redirect...
}
 
return $next($request);
}
 
}

پارامترهای میان‌افزار ممکن است هنگام تعریف مسیر با جدا کردن نام میان‌افزار و پارامترها با علامت مشخص شوند : . چند پارامتر باید با کاما مشخص شوند:

Route::put('post/{id}', function ($id) {
//
})->middleware('role:editor');

میان افزار پایان پذیر

گاهی اوقات ممکن است پس از ارسال پاسخ HTTP به مرورگر، یک میان افزار نیاز به انجام برخی کارها داشته باشد. اگر روشی را در میان افزار خود تعریف کنید terminate و سرور وب شما از FastCGI استفاده می کند، terminate پس از ارسال پاسخ به مرورگر، روش به طور خودکار فراخوانی می شود:

<?php
 
namespace Illuminate\Session\Middleware;
 
use Closure;
 
class StartSession
{
public function handle($request, Closure $next)
{
return $next($request);
}
 
public function terminate($request, $response)
{
// Store the session data...
}
}

متد terminate باید هم درخواست و هم پاسخ را دریافت کند. هنگامی که یک میان افزار پایان پذیر تعریف کردید، باید آن را به لیست میان افزار مسیر یا جهانی در app/Http/Kernel.php فایل اضافه کنید.

هنگام فراخوانی terminate متد در میان‌افزار، لاراول یک نمونه جدید از میان‌افزار را از کانتینر سرویس حل می‌کند . اگر می‌خواهید هنگام فراخوانی متدهای handle و از همان نمونه میان‌افزار استفاده کنید terminate ، میان‌افزار را با استفاده از روش Container در Container ثبت کنید singleton . معمولاً این باید در register روش شما انجام شود AppServiceProvider.php :

use App\Http\Middleware\TerminableMiddleware;
 
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->singleton(TerminableMiddleware::class);
}