در بسیاری از پروژههای تحت وب، ورود کاربران به سیستم بهتنهایی کافی نیست. بعد از اینکه کاربر وارد حساب خود شد، باید مشخص شود که به کدام بخشها دسترسی دارد و اجازه انجام چه عملیاتی را دارد.
برای مثال، در یک فروشگاه اینترنتی ممکن است کاربران عادی بتوانند محصولات را مشاهده کنند، مدیران محصولات جدید بسازند و فقط مالک یک سفارش اجازه مشاهده جزئیات کامل آن را داشته باشد. پیادهسازی چنین محدودیتهایی به سیستمی برای مدیریت مجوزها نیاز دارد.
در Laravel، این مفهوم با نام Authorization شناخته میشود. این فریمورک ابزارهایی مانند Gate، Policy و Middleware را در اختیار توسعهدهندگان قرار میدهد تا بتوانند دسترسی کاربران را بر اساس قوانین مشخص کنترل کنند.
در این مقاله یاد میگیریم Authorization چیست، چه تفاوتی با Authentication دارد، چگونه با Gate و Policy کار کنیم و چطور از دسترسی غیرمجاز به اطلاعات و عملیات حساس جلوگیری کنیم.
Authorization در Laravel چیست؟
Authorization یا مجوزدهی، فرآیندی است که مشخص میکند یک کاربر احراز هویتشده اجازه انجام یک عملیات یا دسترسی به یک منبع مشخص را دارد یا خیر.
فرض کنید در حال توسعه یک سیستم مدیریت پروژه با Laravel هستید. کاربران میتوانند پروژههای خود را مشاهده کنند، اما نباید بتوانند پروژههای خصوصی سایر کاربران را ویرایش یا حذف کنند.
در چنین شرایطی، سیستم باید علاوه بر شناسایی کاربر، مجوز او برای انجام عملیات موردنظر را نیز بررسی کند.
Authorization میتواند موارد زیر را کنترل کند:
- اجازه مشاهده، ایجاد، ویرایش یا حذف اطلاعات
- دسترسی کاربران به سفارشها و پروژههای خود
- مجوز مدیریت محصولات یا کاربران
- محدودیت دسترسی به بخشهای مدیریتی
- بررسی مالکیت یک منبع
- کنترل عملیات بر اساس نقش یا شرایط کاربر
یکی از مزیتهای Laravel این است که میتوانید این قوانین را در ساختاری مشخص تعریف کنید و در بخشهای مختلف برنامه از آنها استفاده کنید.
تفاوت Authentication و Authorization چیست؟
اگرچه Authentication و Authorization به یکدیگر مرتبط هستند، وظایف متفاوتی دارند.
| مفهوم | کاربرد | مثال |
|---|---|---|
| Authentication | تشخیص هویت کاربر | آیا کاربر وارد سیستم شده است؟ |
| Authorization | بررسی مجوز کاربر | آیا کاربر اجازه حذف این محصول را دارد؟ |
برای مثال، مدیر فروشگاه ابتدا باید از طریق Authentication وارد حساب خود شود. سپس Authorization بررسی میکند که آیا او اجازه حذف محصول مشخصی را دارد یا خیر.
بنابراین، احراز هویت موفق به این معنی نیست که کاربر به تمام بخشهای برنامه دسترسی دارد.
نکته مهم این است که Authorization جایگزین Authentication نیست؛ بلکه در کنار آن برای محافظت از منابع و عملیات برنامه استفاده میشود.
روشهای مدیریت Authorization در Laravel
Laravel ابزارهای مختلفی برای کنترل دسترسی ارائه میدهد. انتخاب روش مناسب به پیچیدگی قوانین و ساختار پروژه بستگی دارد.
۱. Gate در Laravel
Gate برای تعریف و بررسی مجوزهای مشخص مناسب است. میتوانید از آن برای پاسخ به پرسشهایی مانند «آیا این کاربر اجازه مشاهده گزارشها را دارد؟» استفاده کنید.
Gate معمولاً زمانی انتخاب مناسبی است که بخواهید یک قانون دسترسی مستقل تعریف کنید و الزاماً به یک مدل یا منبع مشخص وابسته نباشید.
۲. Policy در Laravel
Policy مجموعهای از قوانین مجوزدهی مرتبط با یک مدل یا منبع مشخص است.
برای مثال، اگر پروژه شما دارای مدلهای Post، Product یا Order باشد، میتوانید برای هر مدل Policy جداگانهای تعریف کنید تا مجوز مشاهده، ایجاد، ویرایش و حذف آن منابع را بررسی کند.
Policy در پروژههای متوسط و بزرگ کمک میکند قوانین دسترسی منظمتر و قابل نگهداریتر باشند.
۳. Middleware
Middleware میتواند برای محدود کردن دسترسی به Routeها استفاده شود. Laravel Middlewareهایی مانند auth و can را برای سناریوهای مرتبط ارائه میدهد.
با این حال، باید توجه داشت که Middleware بهتنهایی جایگزین طراحی صحیح قوانین مجوزدهی نیست. قوانین مهم باید در محل مناسب تعریف شوند و هر عملیات حساس واقعاً آنها را بررسی کند.
آموزش Gate در Laravel
برای شروع، یک مثال ساده از Gate ایجاد میکنیم.
فرض کنید در یک سامانه، فقط کاربرانی که مجوز مدیریت گزارشها را دارند باید بتوانند گزارشهای مدیریتی را مشاهده کنند.
در نسخههای جدید Laravel، میتوانید Gate را در فایل app/Providers/AppServiceProvider.php تعریف کنید. اگر ساختار پروژه شما محل دیگری برای ثبت Gateها دارد، تعریف را مطابق همان ساختار انجام دهید.
ابتدا کلاسهای موردنیاز را وارد کنید:
use App\Models\User;
use Illuminate\Support\Facades\Gate;
سپس در متد boot قانون دسترسی را تعریف کنید:
public function boot(): void
{
Gate::define('view-reports', function (User $user) {
return $user->is_admin;
});
}
در این مثال فرض شده است که مدل User دارای فیلد is_admin است. اگر ساختار پروژه شما از نقشها یا مجوزهای دیگری استفاده میکند، باید شرط را مطابق همان ساختار تغییر دهید.
Gate با نام view-reports تعریف شده است. نتیجه بررسی آن باید یک مقدار بولی باشد: true به معنی مجاز بودن عملیات و false به معنی نداشتن مجوز است.
بررسی Gate در Controller
پس از تعریف Gate، میتوانید مجوز را با متد allows بررسی کنید:
use Illuminate\Support\Facades\Gate;
if (Gate::allows('view-reports')) {
// کاربر اجازه مشاهده گزارشها را دارد
}
همچنین میتوانید برای بررسی عدم دسترسی از denies استفاده کنید:
if (Gate::denies('view-reports')) {
abort(403);
}
خطای HTTP با کد 403 نشان میدهد که درخواست به دلیل نداشتن مجوز قابل انجام نیست.
استفاده از Gate در Blade
اگر میخواهید یک دکمه یا بخش از رابط کاربری را فقط برای کاربران مجاز نمایش دهید، میتوانید از دستور @can در Blade استفاده کنید:
@can('view-reports')
<a href="{{ route('reports.index') }}">
مشاهده گزارشها
</a>
@endcan
در این حالت، لینک فقط برای کاربرانی نمایش داده میشود که مجوز view-reports را دارند.
اما یک نکته امنیتی مهم وجود دارد: مخفی کردن دکمه در رابط کاربری بهتنهایی امنیت ایجاد نمیکند. Route یا عملیاتی که پشت این دکمه قرار دارد نیز باید مجوز دسترسی را بررسی کند.
آموزش Policy در Laravel
وقتی قوانین دسترسی به یک مدل یا منبع وابسته هستند، استفاده از Policy معمولاً ساختار مناسبتری ایجاد میکند.
برای مثال، فرض کنید یک سیستم وبلاگ دارید و میخواهید نویسندگان فقط بتوانند مقالههای خود را ویرایش کنند.
مدل Post ممکن است دارای فیلد user_id باشد که مالک مقاله را مشخص میکند.
برای ساخت Policy میتوانید از دستور Artisan استفاده کنید:
php artisan make:policy PostPolicy --model=Post
این دستور یک Policy مرتبط با مدل Post ایجاد میکند. مسیر معمول فایل در پروژههای استاندارد Laravel به شکل زیر است:
app/Policies/PostPolicy.php
با توجه به ساختار پروژه و نسخه Laravel، ممکن است لازم باشد ارتباط Policy با مدل را صریحاً ثبت کنید؛ در بسیاری از ساختارهای استاندارد، Laravel میتواند Policy متناسب را بهصورت خودکار شناسایی کند.
تعریف قانون ویرایش مقاله
در فایل PostPolicy.php میتوان متدی مانند update تعریف کرد:
<?php
namespace App\Policies;
use App\Models\Post;
use App\Models\User;
class PostPolicy
{
public function update(User $user, Post $post): bool
{
return $user->id === $post->user_id;
}
}
این قانون بررسی میکند که شناسه کاربر واردشده با شناسه مالک مقاله یکسان باشد.
اگر این شرط برقرار باشد، کاربر اجازه ویرایش مقاله را دارد؛ در غیر این صورت، مجوز رد میشود.
این مثال یک قانون ساده مالکیت است. در یک پروژه واقعی ممکن است مدیران نیز اجازه ویرایش مقالههای دیگران را داشته باشند. در آن صورت میتوانید شرط مناسب را به قانون اضافه کنید.
بررسی Policy در Controller
فرض کنید کاربر میخواهد مقالهای را ویرایش کند. پس از دریافت مدل Post، میتوانید مجوز را بررسی کنید:
use App\Models\Post;
use Illuminate\Support\Facades\Gate;
public function edit(Post $post)
{
Gate::authorize('update', $post);
return view('posts.edit', compact('post'));
}
در این مثال، Laravel قانون update مربوط به Policy مدل Post را بررسی میکند.
اگر کاربر مجاز نباشد، عملیات متوقف میشود و پاسخ عدم دسترسی تولید خواهد شد.
همچنین میتوانید از متد authorize در Controllerهایی استفاده کنید که از قابلیتهای مربوط به مجوزدهی Laravel در دسترس دارند. انتخاب روش به ساختار Controller شما بستگی دارد.
استفاده از Policy در Blade
برای نمایش دکمه ویرایش فقط به مالک مقاله، میتوانید بنویسید:
@can('update', $post)
<a href="{{ route('posts.edit', $post) }}">
ویرایش مقاله
</a>
@endcan
این روش باعث میشود رابط کاربری متناسب با مجوز کاربر نمایش داده شود. با این حال، همچنان باید عملیات ویرایش در سمت سرور نیز مجوزدهی شود.
تفاوت Gate و Policy در Laravel
هر دو ابزار برای مدیریت مجوزها استفاده میشوند، اما کاربرد معمول آنها متفاوت است.
| ویژگی | Gate | Policy |
|---|---|---|
| کاربرد متداول | قوانین مستقل دسترسی | قوانین مرتبط با یک مدل |
| ساختار | تعریف مجوز با نام مشخص | مجموعهای از متدهای مجوزدهی |
| مثال | اجازه مشاهده گزارشها | اجازه ویرایش یک مقاله |
| مناسب برای | قوانین ساده و مستقل | منابعی مانند Post، Product و Order |
این تفاوت یک قانون اجباری نیست. میتوان Gateهایی داشت که به دادههای مختلف وابستهاند و Policyهایی با منطق پیچیده تعریف کرد. بهتر است ابزاری را انتخاب کنید که قوانین دسترسی پروژه را روشنتر و قابل نگهداریتر کند.
محافظت از Routeها با مجوزها در Laravel
در Laravel میتوانید از Middleware با نام can برای بررسی مجوز پیش از اجرای Route استفاده کنید.
برای مثال، فرض کنید مسیر ویرایش یک مقاله باید فقط برای کاربران مجاز قابل دسترسی باشد:
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;
Route::get('/posts/{post}/edit', [
PostController::class,
'edit',
])->middleware([
'auth',
'can:update,post',
]);
در این مثال، ابتدا Middleware احراز هویت بررسی میکند که کاربر وارد سیستم شده باشد. سپس مجوز update برای مدل Post بررسی میشود.
این مثال بر اساس این فرض نوشته شده است که مدل Post از طریق Route Model Binding در پارامتر post در دسترس است و Policy مربوط به آن نیز بهدرستی شناسایی شده است.
اگر کاربر وارد سیستم نشده باشد، رفتار Middleware احراز هویت اجرا میشود. اگر وارد شده باشد اما مجوز لازم را نداشته باشد، درخواست با پاسخ عدم دسترسی متوقف میشود.
برای گروهی از مسیرها نیز میتوانید Middlewareهای مرتبط را در سطح گروه تعریف کنید، به شرطی که قوانین دسترسی هر عملیات بهدرستی بررسی شوند.
کنترل دسترسی بر اساس نقش کاربران
در بسیاری از پروژهها، کاربران نقشهای مختلفی دارند؛ برای مثال:
- مدیر سیستم
- مدیر فروشگاه
- کارمند
- مشتری
- نویسنده
- کاربر عادی
یکی از روشهای مدیریت دسترسی، تعریف نقشها و بررسی نقش کاربر هنگام تصمیمگیری درباره مجوزها است.
برای مثال، اگر مدل User دارای ویژگی is_admin باشد، میتوانید در یک Gate از آن استفاده کنید. اما برای پروژههایی با نقشها و مجوزهای متعدد، بهتر است ساختار مشخصی برای مدیریت Role و Permission طراحی کنید.
نکته مهم این است که نقش و مجوز یکسان نیستند. نقش معمولاً مجموعهای از مسئولیتها را مشخص میکند، در حالی که مجوز به یک عملیات مشخص اشاره دارد.
برای مثال، نقش «مدیر محتوا» میتواند شامل مجوزهای ایجاد، ویرایش و انتشار مقاله باشد. این طراحی به شما اجازه میدهد دسترسیها را بهصورت منظمتری مدیریت کنید.
اگر تعداد نقشها و مجوزها در پروژه زیاد است، میتوانید از راهکارهای استاندارد یا بستههای معتبر مدیریت Role و Permission استفاده کنید. انتخاب روش باید با نیاز پروژه و ساختار امنیتی آن هماهنگ باشد.
بررسی مالکیت منابع در پروژههای Laravel
یکی از خطاهای امنیتی رایج این است که برنامه فقط بررسی میکند کاربر وارد سیستم شده باشد، اما مالکیت منبع را بررسی نمیکند.
فرض کنید آدرس مشاهده سفارش به این شکل باشد:
/orders/150
اگر کاربر بتواند شماره سفارش را تغییر دهد و اطلاعات سفارش شخص دیگری را مشاهده کند، سیستم دچار مشکل کنترل دسترسی شده است.
برای جلوگیری از این وضعیت، باید بررسی کنید که کاربر اجازه مشاهده همان سفارش مشخص را دارد.
میتوانید این منطق را در Policy تعریف کنید:
public function view(User $user, Order $order): bool
{
return $user->id === $order->user_id;
}
در این مثال، فقط مالک سفارش اجازه مشاهده آن را دارد.
در یک سیستم واقعی، ممکن است مدیران یا تیم پشتیبانی نیز تحت شرایط مشخصی مجاز به مشاهده سفارش باشند. در این صورت، باید آن استثناها را بهصورت روشن و قابل آزمون به قانون اضافه کنید.
اصل مهم این است که مجوز دسترسی باید بر اساس منبع واقعی درخواست بررسی شود، نه صرفاً بر اساس اینکه کاربر وارد حساب خود شده است.
تفاوت احراز هویت و کنترل دسترسی در APIهای Laravel
در APIها نیز باید هویت درخواستکننده و مجوز او را جداگانه بررسی کنید.
برای مثال، ممکن است یک درخواست API از نظر احراز هویت معتبر باشد، اما کاربر اجازه حذف محصول مشخصی را نداشته باشد.
در چنین شرایطی، ابتدا روش Authentication باید هویت کاربر را مشخص کند و سپس Authorization مجوز عملیات را بررسی کند.
در Laravel، ابزارهایی مانند Policy و Gate میتوانند در منطق مجوزدهی API نیز استفاده شوند. روش احراز هویت به نوع کلاینت و معماری API بستگی دارد؛ برای برخی سناریوها، Laravel Sanctum گزینه مناسبی است.
نباید تصور کنید که استفاده از توکن معتبر بهتنهایی به معنی اجازه دسترسی به تمام منابع API است. مجوزهای هر عملیات باید جداگانه و متناسب با نیاز سیستم بررسی شوند.
خطاهای رایج در پیادهسازی Authorization
۱. فقط مخفی کردن دکمهها در رابط کاربری
مخفی کردن دکمه حذف یا ویرایش در Blade کافی نیست. کاربر ممکن است درخواست را مستقیماً به سرور ارسال کند. عملیات حساس باید در سمت سرور نیز مجوزدهی شود.
۲. بررسی نکردن مالکیت دادهها
وارد بودن کاربر به سیستم به این معنی نیست که میتواند اطلاعات تمام کاربران را مشاهده کند. منابعی مانند سفارشها، پروژهها و مقالهها باید بر اساس مالکیت یا مجوزهای تعریفشده محافظت شوند.
۳. تکرار قوانین دسترسی در چند Controller
اگر یک قانون مشابه در چند نقطه از برنامه تکرار شود، احتمال ناسازگاری و خطا افزایش پیدا میکند. Gate و Policy به شما کمک میکنند قوانین دسترسی را در محل مشخصی نگهداری کنید.
۴. اعتماد به اطلاعات ارسالی از مرورگر
نباید فقط بر اساس مقادیری مانند is_admin که از سمت کاربر ارسال میشوند تصمیم بگیرید. اطلاعات حساس مربوط به نقشها و مجوزها باید از منبع معتبر سمت سرور بررسی شوند.
۵. تست نکردن کاربران غیرمجاز
هنگام آزمایش قابلیتها، فقط حالت دسترسی مجاز را بررسی نکنید. باید مطمئن شوید کاربر غیرمجاز نمیتواند از طریق Route مستقیم، درخواست API یا تغییر شناسه منبع به اطلاعات محافظتشده دسترسی پیدا کند.
بهترین روشها برای پیادهسازی Authorization در Laravel
برای ساخت یک سیستم دسترسی امن و قابل نگهداری، نکات زیر را در نظر بگیرید:
- قوانین مستقل و ساده را با Gate تعریف کنید.
- برای مدلهایی مانند Post، Product و Order از Policy استفاده کنید.
- در Routeهای محافظتشده، احراز هویت و مجوزدهی را متناسب با نیاز اعمال کنید.
- مالکیت منابع را بهصورت صریح بررسی کنید.
- قوانین دسترسی را در سمت سرور اجرا کنید.
- نقشها و مجوزها را از اطلاعات قابل دستکاری کاربر دریافت نکنید.
- برای دسترسی مجاز و غیرمجاز تست بنویسید.
- قوانین پیچیده را مستند کنید تا در آینده قابل نگهداری باشند.
همچنین بهتر است پاسخهای خطا را با دقت طراحی کنید. در بسیاری از موارد، پاسخ 403 برای کاربری که منبع را میشناسد اما مجوز دسترسی ندارد مناسب است. در برخی سناریوها، ممکن است بخواهید وجود منبع را از کاربر غیرمجاز پنهان کنید و پاسخ دیگری برگردانید؛ این تصمیم باید آگاهانه و متناسب با نیاز امنیتی برنامه گرفته شود.
پرسشهای متداول درباره Authorization در Laravel
Authorization در Laravel چیست؟
Authorization فرآیندی است که مشخص میکند کاربر اجازه انجام یک عملیات یا دسترسی به یک منبع را دارد یا خیر. Laravel ابزارهایی مانند Gate، Policy و Middleware را برای پیادهسازی این منطق فراهم میکند.
تفاوت Gate و Policy در Laravel چیست؟
Gate برای تعریف قوانین مستقل دسترسی مناسب است؛ Policy معمولاً مجموعهای از قوانین مرتبط با یک مدل یا منبع مشخص را در یک کلاس نگهداری میکند.
آیا برای استفاده از Authorization باید کاربر وارد سیستم شده باشد؟
در بسیاری از سناریوها، بله؛ ابتدا هویت کاربر با Authentication مشخص میشود و سپس مجوز او بررسی میشود. با این حال، Laravel امکان تعریف قوانین دسترسی متناسب با شرایط مختلف را نیز فراهم میکند.
چگونه در Laravel فقط مالک یک مقاله را مجاز به ویرایش کنیم؟
میتوانید در Policy مدل Post، شناسه کاربر فعلی را با شناسه مالک مقاله مقایسه کنید و نتیجه را بهعنوان مجوز ویرایش برگردانید.
آیا استفاده از Middleware برای Authorization کافی است؟
Middleware میتواند پیش از اجرای Route مجوز را بررسی کند، اما مهمتر از محل بررسی، کامل بودن قانون دسترسی است. تمام عملیات حساس باید در سمت سرور محافظت شوند و نباید صرفاً به مخفی کردن بخشهایی از رابط کاربری اکتفا کرد.
آیا Authorization در API هم کاربرد دارد؟
بله. Gate و Policy میتوانند برای کنترل مجوزهای کاربران در API نیز استفاده شوند. البته احراز هویت درخواست API و بررسی مجوز عملیات، دو مرحله مجزا هستند.
جمعبندی
Authorization یکی از بخشهای مهم توسعه نرمافزارهای امن با Laravel است. این قابلیت به شما کمک میکند مشخص کنید هر کاربر به کدام منابع دسترسی دارد و چه عملیاتی را میتواند انجام دهد.
در این مقاله با تفاوت Authentication و Authorization، تعریف Gate، ساخت Policy، بررسی مجوزها در Controller و Blade، محافظت از Routeها و کنترل مالکیت منابع آشنا شدیم.
برای پروژههای کوچک، Gate میتواند راهکاری ساده و کاربردی باشد؛ اما در پروژههایی که مدلها و عملیات متعددی دارند، Policy معمولاً به سازماندهی بهتر قوانین دسترسی کمک میکند.
در ادامه مسیر یادگیری Laravel، پیشنهاد میکنیم مقاله بعدی این مجموعه یعنی Laravel Sanctum را مطالعه کنید تا با یکی از ابزارهای مهم احراز هویت API و برخی برنامههای مبتنی بر SPA آشنا شوید.





