مجوزها و دسترسی (Authorization)
Authorizer هستهی کنترل دسترسی و مجوزها در پکیج access-hub است و به شما کمک میکند نقشها، مجوزها و دسترسی کاربران را بهصورت منسجم مدیریت کنید.
این کلاس معمولاً در کنار Authenticator استفاده میشود؛ جایی که Authenticator مسئول احراز هویت است و Authorizer مسئول این است که کاربر احراز هویتشده به چه چیزهایی دسترسی دارد.
Dornica\AccessHub\Authorization
روش های استفاده
برای استفاده از کلاس Authorizer و متدهای آن، دو روش وجود دارد:
استفاده مستقیم از کلاس با use
ابتدا کلاس را ایمپورت کرده و سپس با استفاده از Scope Resolution Operator (::) مستقیماً به متدهای آن دسترسی پیدا میکنید:
use Dornica\AccessHub\Authorization\Facades\Authorizer;
Authorizer::getRoles(); // فراخوانی متد به صورت مستقیم از کلاس
استفاده از تابع کمکی authorizer
در زیرساخت یک helper function برای دسترسی به Authorizer تعریف شده است:
authorizer()->getRoles();
authorizer()->hasAccess('permission_name');
معمولا در مثالهای این مستندات فرض میشود شما از طریق یکی از این روشها به متدهای Authorizer دسترسی دارید. بنابراین میتوانید بسته به نیاز خود، هریک از این رویکردها را انتخاب و استفاده کنید.
امکانات اصلی Authorizer
در جدول زیر مهمترین امکانات ارائهشده توسط Authorizer را مشاهده میکنید:
| شرح | متد / بخش |
|---|---|
| دریافت لیست نقشها از کش مرکزی | Roles |
| دریافت لیست مجوزها از کش مرکزی | Permissions |
| دریافت دستهبندیهای مجوزها از کش مرکزی | Permission Categories |
| مدیریت نقشهای کاربران (اختصاص و حذف نقش) | Role Management |
| مدیریت مجوزهای هر نقش (اتصال/حذف Permission به/از Role) | Role Permissions |
| مدیریت مجوزهای مستقیم کاربران برای یک نقش خاص | User Direct Permissions |
| دریافت لیست مجوزهای کاربر و گروهبندی آنها بر اساس دستهبندی | Permission Queries |
| بررسی مجوز کاربر (یا نقش مشخص) | hasAccess |
| Directive برای بررسی مجوز کاربر | canAccess |
| بررسی فعال بودن سرویس Authorization از روی کانفیگ | isEnabled |
لیست نقشها (Roles)
Authorizer با استفاده از DynamicCacheStorageAccess لیست نقشها را در کش نگه میدارد تا بازیابی آن سریع و کمهزینه باشد.
متدهای Magic مرتبط با نقشها
Authorizer::getRoles(): Collection
Authorizer::forgetRoles(): bool
Authorizer::refreshRoles(): bool
توضیحات
getRolesلیست کامل نقشهای سیستم را از کش یا منبع دادهی اصلی برمیگرداند.forgetRolesدادهی کششدهی نقشها را حذف میکند.refreshRolesدادهی نقشها را از منبع اصلی دوباره میخواند و در کش بهروزرسانی میکند.
مثال
use Dornica\AccessHub\Authorization\Facades\Authorizer;
// دریافت نقشها
$roles = Authorizer::getRoles();
// رفرش کش نقشها
Authorizer::refreshRoles();
لیست مجوزها (Permissions)
مشابه نقشها، مجوزها نیز در کش نگهداری میشوند تا درخواستهای مکرر برای بررسی دسترسی، سریعتر انجام شوند.
متدهای Magic مرتبط با مجوزها
Authorizer::getPermissions(): Collection
Authorizer::forgetPermissions(): bool
Authorizer::refreshPermissions(): bool
توضیحات
getPermissionsلیست کامل مجوزهای ثبتشده در سیستم را برمیگرداند.forgetPermissionsکش مربوط به مجوزها را خالی میکند.refreshPermissionsمجوزها را از منبع اصلی دوباره بارگذاری و در کش ذخیره میکند.
مثال
use Dornica\AccessHub\Authorization\Facades\Authorizer;
// دریافت لیست مجوزها برای نمایش در پنل مدیریت
$permissions = Authorizer::getPermissions();
دستهبندیهای مجوزها (Permission Categories)
برای سازماندهی بهتر مجوزها در UI، مجوزها معمولاً در دستههای مختلف گروهبندی میشوند.
Authorizer این دستهبندیها را نیز در کش نگه میدارد.
متدهای Magic مرتبط با دستهبندی مجوزها
Authorizer::getPermissionCategories(): Collection
Authorizer::forgetPermissionCategories(): bool
Authorizer::refreshPermissionCategories(): bool
مثال
use Dornica\AccessHub\Authorization\Facades\Authorizer;
$categories = Authorizer::getPermissionCategories();
مدیریت نقش کاربران (Role Management)
این متدها برای اختصاص و حذف نقش از کاربران استفاده میشوند و بهصورت خودکار وضعیت Super Admin و مجوزهای مرتبط را بهروزرسانی میکنند.
متدهای کلیدی
assignRole(string|int $userId, string|int $roleId, ?array $attributes = []): object
removeRole(string|int $userId, string|int $roleId): bool
مثال: اختصاص نقش به کاربر
use Dornica\AccessHub\Authorization\Facades\Authorizer;
// اختصاص نقش با شناسه ۳ به کاربر با شناسه ۱۰
$userRole = Authorizer::assignRole(10, 3, [
'expired_at' => null,
]);
مثال: حذف نقش از کاربر
use Dornica\AccessHub\Authorization\Facades\Authorizer;
Authorizer::removeRole(10, 3);
مدیریت مجوزهای نقش (Role Permissions)
برای مدیریت اینکه هر Role چه Permissionهایی دارد، از متدهای زیر استفاده کنید. این متدها صرفاً نگاشت نقش ↔ مجوز را مدیریت میکنند و روی کاربران بهطور مستقیم اعمال نمیشوند.
متدهای کلیدی
attachPermissionToRole(string|int $roleId, string|int|array $permissionIds): bool
detachPermissionFromRole(string|int $roleId, string|int|array $permissionIds): bool
مثال
use Dornica\AccessHub\Authorization\Facades\Authorizer;
// اضافه کردن چند دسترسی به یک نقش
Authorizer::attachPermissionToRole(3, [10, 11, 12]);
// حذف یک دسترسی از نقش
Authorizer::detachPermissionFromRole(3, 10);
مجوزهای مستقیم کاربران (User Direct Permissions)
این متدها برای زمانی است که میخواهید صرفنظر از Role، به یک کاربر (یا چند کاربر) مجوزهای خاصی را مستقیماً بدهید یا از او بگیرید. این مجوزها معمولاً در کنار مجوزهای Role استفاده میشوند.
متدهای کلیدی
attachPermissionToUser(
string|int|array $userIds,
string|int|array $permissionIds,
string|int $roleId
): void
detachPermissionFromUser(
string|int|array $userIds,
string|int|array $permissionIds,
string|int $roleId
): void
syncUserPermissions(
string|int|array $userIds,
string|int|array $permissionIds,
string|int $roleId
): void
copyPermissions(
string|int $fromUserId,
string|int $toUserId,
string|int $roleId = null,
?array $attributes = []
): void
مثالها
use Dornica\AccessHub\Authorization\Facades\Authorizer;
// اضافه کردن چند دسترسی مستقیم به چند کاربر در یک نقش
Authorizer::attachPermissionToUser(
userIds: [10, 11],
permissionIds: [100, 101],
roleId: 3
);
// حذف چند دسترسی مستقیم از کاربران
Authorizer::detachPermissionFromUser(
userIds: [10, 11],
permissionIds: [100],
roleId: 3
);
// جایگزینی کامل لیست دسترسی های مستقیم کاربران برای یک نقش
Authorizer::syncUserPermissions(
userIds: [10, 11],
permissionIds: [200, 201, 202],
roleId: 3
);
// کپیکرد ن مجوزهای فعال یک کاربر به کاربر دیگر (برای نقش خاص)
Authorizer::copyPermissions(
fromUserId: 10,
toUserId: 20,
roleId: 3
);
بعد از هر تغییر در مجوزهای مستقیم، وضعیت has_special_permission روی مدل کاربر مطابق کد بهروزرسانی میشود تا بتوانید وجود مجوزهای ویژه را بهسادگی تشخیص دهید.
دریافت لیست مجوزهای کاربر (Permission Queries)
برای نمایش یا گزارشگیری از مجوزهای یک کاربر، میتوانید از متدهای Query محور زیر استفاده کنید.
متدهای کلیدی
getUserPermissions(string|int $userId, string|int|null $roleId = null): array
getUserPermissionsByCategories(string|int $userId, string|int|null $roleId = null): array
خروجی نمونه
[
'userId' => 10,
'permissions' => [
['id' => 1, 'name' => 'مشاهده کاربران', 'is_special' => false],
// ...
],
]
[
'userId' => 10,
'permissionsByCategory' => [
'مدیریت کاربران' => [
['id' => 1, 'name' => 'مشاهده کاربران', 'slug' => 'users.view', 'is_special' => false],
// ...
],
// ...
],
]
مثال
use Dornica\AccessHub\Authorization\Facades\Authorizer;
$flat = Authorizer::getUserPermissions(10);
$grouped = Authorizer::getUserPermissionsByCategories(10);
بررسی دسترسی با hasAccess
hasAccess(string $slug, object $role = null, mixed $user = null, $onlyOne = true): bool
پارامترها
| نام | نوع | توضیح |
|---|---|---|
| slug | string|array | اسلاگ یا اسلاگ های مجوز هایی که میخواهید بررسی کنید. |
| role | object|null | (اختیاری) نقش خاصی که میخواهید دسترسی را برای آن بررسی کنید. |
| user | mixed | (اختیاری) کاربر خاصی که میخواهید دسترسی را برای او بررسی ک نید. |
| onlyOne | bool | (اختیاری) با غیر فعال کردن این پارامتر باید کاربر به تمامی اسلاگ های وارد شده دسترسی داشته باشد. |
توضیح
متد hasAccess بررسی میکند که آیا کاربر (یا نقش مشخصشده) مجوزی با اسلاگ دادهشده دارد یا خیر.
در صورت ارسال پارامتر user یا role، این مقادیر بهطور موقت روی authenticator ست میشوند و سپس لیست مجوزهای محاسبهشده برای همان کاربر/نقش بررسی خواهد شد.
مثال ساده
if (!hasAccess('admin.users.magagement.index')) {
abort(403, 'شما مجوز دسترسی را ندارید');
}
مثال با کاربر/نقش خاص
// بررسی دسترسی برای یک کاربر مشخص (بدون نیاز به لاگین بودن او در سشن فعلی)
if (hasAccess('admin.reports.index', $role, $user)) {
// کاربر/نقش به این گزارش دسترسی دارد
}
مثال با وارد کردن چندین اسلاگ
// بررسی تمامی دسترسی های وارد شده و اگر کاربر به یکی از دسترسی های وارد شده دسترسی داشته باشد مقدار شرط true می شود
if (hasAccess(['admin.reports.index' , 'admin.settings.index'])) {
// نمایش در صورت دسترسی به تنظیمات یا گزارش
}
// با دادن مقدار false به onlyOne باید کاربر به تمامی موارد دسترسی داشته باشد
if (hasAccess(slug: ['admin.reports.index' , 'admin.settings.index'], onlyOne: false)) {
// نمایش در صورت دسترسی کاربر به تنظیمات و گزارش به صورت همزمان
}
مثال استفاده از hasAccess در Authorizer
use Dornica\AccessHub\Authorization\Facades\Authorizer;
//نکته : اگر از روش استفاده کنید فقط می توانید دسترسی یک اسلاگ مشخص را بررسی کنید .
if (!Authorizer::hasAccess('admin.users.magagement.index')) {
//نمایش گزارش
}
این متد برای استفاده در Policyها، Middlewareها و لایهی سرویس توصیه میشود تا منطق مجوزها در یک نقطهی متمرکز قرار بگیرد.
بررسی دسترسی با canAccess
@canAccess(string $slug, object $role = null, mixed $user = null, $onlyOne = true): bool
پارامترها
| نام | نوع | توضیح |
|---|---|---|
| slug | string|array | اسلاگ یا اسلاگ های مجوز هایی که میخواهید بررسی کنید. |
| role | object|null | (اختیاری) نقش خاصی که میخواهید دسترسی را برای آن بررسی کنید. |
| user | mixed | (اختیاری) کاربر خاصی که میخواهید دسترسی را برای او بررسی کنید. |
| onlyOne | bool | (اختیاری) با غیر فعال کردن این پارامتر باید کاربر به تمامی اسلاگ های وارد شده دسترسی داشته باشد. |
توضیح
این directive دقیقا مانند hasAccess می باشد و عملکرد یکسانی با آن دارد .
مثال ساده
@canAccess('admin.basic.banks.store')
{!! FormValidator::formRequest(Modules\Bank\Http\Requests\StoreBankRequest::class, "#create-bank") !!}
@endcanAccess
مثال با کاربر/نقش خاص
// بررسی دسترسی برای یک کاربر مشخص (بدون نیاز به لاگین بودن او در سشن فعلی)
@canAccess('admin.basic.banks.store', $role, $user)
{!! FormValidator::formRequest(Modules\Bank\Http\Requests\StoreBankRequest::class, "#create-bank") !!}
@endcanAccess
مثال با وارد کردن چندین اسلاگ
// بررسی تمامی دسترسی های وارد شده و اگر کاربر به یکی از دسترسی های وارد شده دسترسی داشته باشد مقدار شرط صحیح می شود
@canAccess(['admin.basic.banks.store', 'admin.basic.banks.create'])
{!! FormValidator::formRequest(Modules\Bank\Http\Requests\StoreBankRequest::class, "#create-bank") !!}
@endcanAccess
// با دادن مقدار false به onlyOne باید کاربر به تمامی موارد دسترسی داشته باشد
@canAccess(slug: ['admin.basic.banks.store', 'admin.basic.banks.create'], onlyOne : false)
{!! FormValidator::formRequest(Modules\Bank\Http\Requests\StoreBankRequest::class, "#create-bank") !!}
@endcanAccess
بررسی فعال بودن سرویس Authorization
در بعضی محیطها ممکن است سرویس Authorization بهصورت کامل غیرفعال باشد (مثلاً در تستهای ساده یا محیطهای خاص).
برای بررسی این موضوع میتوانید از متد زیر استفاده کنید:
authorizer()->isEnabled(): bool
این متد مقدار تنظیم authorization.enable را از فایل کانفیگ dornica-access-hub خوانده و برمیگرداند.
نکات مهم و ملاحظات فنی
- هماهنگی با Authenticator:
Authorizer::hasAccessبرای تشخیص کاربر و نقش فعلی ازauthenticatorاستفاده میکند؛ اطمینان حاصل کنید که جریان احراز هویت (Login) بهدرستی پیادهسازی شده باشد. - استفاده در لایهی Policy/Middleware: توصیه میشود منطق دسترسی بهجای قرار گرفتن در Controllerها، در Policyها یا Middlewareها و با استفاده از
hasAccessپیاده شود. - مدیریت کش: بعد از اعمال تغییرات روی نقشها، مجوزها یا دستهبندی آنها، متدهای
refreshرا صدا بزنید تا دادههای کششده با وضعیت جدید همگام شوند.