آموزش مقدماتی لاراول - تعریف دسترسی با کمک Middleware

در این مقاله امکان ثبت نام و عضویت کاربران را به پروژه اضافه کردیم در ادامه و در این مقاله قصد داریم با کمک Middleware در لاراول برای کاربران دسترسی و محدودیت را تعریف کنیم. تعریف درست و دقیق دسترسی ها یکی از مهمترین قسمت ها در هر وبسایت هست و باید به درستی انجام بشه! برای نمونه نمی‌خواهیم هر کسی که وارد سایت ما میشه امکان درج آهنگ جدید رو داشته باشه! این یعنی دسترسی افزودن یک آهنگ برای کسانی که عضو سیستم نیستن باید محدود شود. با کمک Middleware در لاراول می‌توان این سطح دسترسی ها را تعریف کرد.


همون طور که از نام Middleware مشخصه Middleware ها دستوراتی هستند که مابین درخواست ما به سرور و پاسخی که سرور به ما میدهد قرار می گیرند. شما احتمالاً با Middleware Auth آشنا هستید جایی که درخواست شما برای یک عملیات مثلاً ویرایش نام کاربریتان در یک سایت شما را به صفحه لاگین هدایت می‌کند دلیل این اتفاق باطل شدن سشن هویت کاربری شما در آن سایت است که به موجب آن باید مجدداً سشن خود را به روز رسانی کنید. 

خب بیایید به پروژه خودمان برگردیم. اگر وارد مسیر ‍app/Http/Middleware بشوید Middlewareهایی از پیش تعریف شده‌ای را خواهید دید. برای نمونه یکی از این Middleware‌ها  PreventRequestsDuringMaintenance هست و برای زمانی که می‌خواهید سرویس خودتون رو بروز رسانی کنید با فعال کردن این وضعیت کاربران با خطای ۵۰۳ یا در دسترس نبودن سرویس مواجه خواهند شد در لاراول برای فعال کردن این وضعیت از دستور ‍php artisan down استفاده میشه و برای توقف این حالت از دستور php artisan up استفاده میکنیم. یکی دیگر از Middlewareهایی که برای ما اهمیت دارد Authenticate است که با کمک آن امکان ایجاد یک آهنگ جدید برای افرادی که کاربر سیستم نیستند رو سلب میکنه! 

خب بیاید دسترسی برای کار با آهنگ ها را در پروژه خودمون تعریف بکنیم. برای این کار به فایل مسیر web.php بروید و با کمک تابع middleware برای آهنگ‌ها دسترسی رو به صورت زیر تعریف کنید:

Route::resource('songs', SongController::class)->middleware('auth');

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

public function __construct()
{
	$this->middleware('auth');
}

در اینجا توابع دیگری به نام only و except و وجود داره که میتونید با کمک اونها دسترسی رو تنها بر روی مسیرهایی که میخوایم تعریف کنیم:

public function __construct()
{
	$this->middleware('auth')->except(['index', 'show']);
}

همانطور که مشاهده می‌کنید امکان مشاهده آهنگ‌ها وجود داره ولی اگر بخوایید آهنگ جدید وارد کنید یا آهنگی رو ویرایش یا حذف کنید در اینصورت شما به صفحه لاگین هدایت خواهید شد!

ساخت یک Middleware

حالا اجازه بدید یک middleware سفارشی ایجاد کنیم. برای اینکار از دستور artisan زیر استفاده می‌کنیم:

php artisan make:middleware SampleMiddleware 

خب برای استفاده از این middleware باید ابتدا در فایل kernel.php درون فولدر Http تعریف کنیم. بیایید کمی به فایل kernel.php دقیق نگاه کنیم. این فایل ۳ آرایه داره که هرکدوم برای هدف خاصی تعریف شدند. 

اولین آرایه به نام middleware$ هست و برای middlewareهایی هست که بصورت گلوبال روی تمام درخواست‌ها اعمال میشوند بیایید وارد SampleMiddleware بشیم و تابع handle رو بصورت زیر تغییر بدیم:

public function handle(Request $request, Closure $next)
{
	dd('hello from middleware' );
	
	return $next($request);
}

حالا به kernel.php برگردید و به آرایه  middleware$ کلاس SampleMiddleware رو اضافه کنید. خواهید دید که به هر مسیر سایت که برید خروجی پیغام 'hello from middleware' رو خواهید دید.

اما آرایه بعدی بنام middlewareGroups$ برای middlewareهایی هست که تنها روی یک فایل در route اعمال میشوند. برای مثال اگر کلاس SampleMiddleware را به middlewareGroups$ و برای مسیرهای web اضافه کنیم این middleware برای تمامی مسیرهایی که در web ساختیم اعمال میشه ولی روی مسیرهای api تاثیر نخواهد داشت. در آخر هم آرایه routeMiddleware$ رو داریم. در این آرایه همراه با یک کلید تعریف میشن و این به ما قابلیت اعمال یک middleware روی تنها یک مسیر رو خواهد داد. اگر لیست رو مشاهده کنید 'auth' رو میبینید که در بالا هم به اون اشاره شد و دیدید که چطور میتونیم اون رو به مسیرهای که مایل هستیم اعمال کنیم.

خب حالا بیایید یک کار جالب انجام بدیم. ابتدا یک کاربر جدید با نام ali ثبت‌نام کنید بعد به SampleMiddleware برید و دستور زیر رو بزنید:

public function handle(Request $request, Closure $next)
{
	if (Auth::check() && Auth::user()->name == 'Ali')
		return response('علی جان حساب کاربری شما محدود شد 😄😄');

	return $next($request);
}

سپس وارد kernel میشیم و آدرس middlewareیی که ساختیم رو به انتهایی آرایه routeMiddleware اضافه می‌کنیم:

Image for post
Image for post

درنهایت وارد web میشیم و بر روی resource آهنگها کلید middlewareیی که ساختیم رو اعمال می‌کنیم یعنی 'test' 

حالا هر موقع علی ما وارد سایت بشه و بخواد آهنگی رو ببینه با پیغام ما مواجه میشه :)