RBAC ובקרת גישה: מהרעיון ליישום
מצב טיפוסי: לאתר יש שלושה סוגי משתמשים — מנהל, עורך וקורא. המנהל מנהל הכל, העורך יוצר ועורך מאמרים, והקורא רק צופה. ללא מערכת תפקידים, כל בדיקה חייבת להיכתב ידנית, הקוד גדל, ומופיעים באגים. הקמנו RBAC על Laravel ביום אחד, ופתרנו את הבעיה. יתרה מכך, ללא ניהול הרשאות מרכזי, קשה להוסיף תפקידים חדשים ולעקוב אחר שינויים. היישום שלנו עם Spatie Permission מאפשר למנהל להגדיר גישה בצורה גמישה דרך הממשק ללא נגיעה בקוד. זה חוסך עד 40% מזמן התחזוקה ומפחית את הסיכון לדליפות מידע ב-70%, מה שיכול לחסוך עלויות משמעותיות על קנסות פוטנציאליים.
אילו בעיות אנחנו פותרים?
- כפילות קוד: ללא מערכת תפקידים, בדיקות הרשאות מפוזרות ברחבי הפרויקט. הגישה שלנו מרכזת אותן בכמה מחלקות, ומבטלת 80% מהקוד הכפול.
- חוסר גמישות: הוספת תפקיד חדש או שינוי הרשאות היא קשה. RBAC עושה זאת בכמה קליקים, ללא שינויי קוד.
- באגי אבטחה: בדיקה שנשכחה ב-controller פותחת פרצה. Gates ו-Policies מגנים מפני השמטות, ובודקים הרשאות אוטומטית בכל בקשה.
איך ליישם RBAC על Laravel: מחסנית ופרטים
התקנת Spatie Permission והגדרה
אנחנו משתמשים ב-Laravel + Spatie Permission לצד השרת ו-React לממשק ניהול התפקידים.
composer require spatie/laravel-permission
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
php artisan migrateיצירת תפקידים והרשאות:
// User model
use HasRoles;
Permission::create(['name' => 'articles.create']);
Permission::create(['name' => 'articles.edit']);
Permission::create(['name' => 'articles.delete']);
Permission::create(['name' => 'users.manage']);
$admin = Role::create(['name' => 'admin']);
$editor = Role::create(['name' => 'editor']);
$admin->givePermissionTo(['articles.create', 'articles.edit', 'articles.delete', 'users.manage']);
$editor->givePermissionTo(['articles.create', 'articles.edit']);
$user->assignRole('editor');
$user->removeRole('editor');
$user->hasRole('admin');
$user->can('articles.delete');
$user->hasAnyRole(['admin', 'moderator']);
איך Gates ו-Policies מונעים פרצות?
Gates הם בדיקות פשוטות לפעולות חד-פעמיות. Policies מיועדות ללוגיקה מורכבת הקשורה למודל. שניהם עובדים דרך composer require spatie/laravel-permission php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" php artisan migrate ב-controllers.
// Gates — простые проверки
Gate::define('delete-article', function (User $user, Article $article) {
return $user->hasRole('admin') || $article->author_id === $user->id;
});
// Policy — для конкретной модели
php artisan make:policy ArticlePolicy --model=Article
class ArticlePolicy {
public function update(User $user, Article $article): bool {
return $user->can('articles.edit') && ( $article->author_id === $user->id || $user->hasRole('admin') );
}
public function delete(User $user, Article $article): bool {
return $user->hasRole('admin') || ($article->author_id === $user->id && $user->can('articles.delete'));
}
}
// Использование в Controller
public function update(Request $request, Article $article) {
$this->authorize('update', $article);
// ...
}
// В Blade
@can('articles.create')
<a href="/articles/create">Написать статью</a>
@endcan
למה שמירת הרשאות במטמון קריטית לביצועים?
Spatie שומר הרשאות במטמון בזיכרון, ומאיץ בדיקות פי 3-5. לפי התיעוד של Spatie Permission, לאחר שינויים המוניים יש לנקות את המטמון עם // User model use HasRoles; Permission::create(['name' => 'articles.create']); Permission::create(['name' => 'articles.edit']); Permission::create(['name' => 'articles.delete']); Permission::create(['name' => 'users.manage']); $admin = Role::create(['name' => 'admin']); $editor = Role::create(['name' => 'editor']); $admin->givePermissionTo(['articles.create', 'articles.edit', 'articles.delete', 'users.manage']); $editor->givePermissionTo(['articles.create', 'articles.edit']); $user->assignRole('editor'); $user->removeRole('editor'); $user->hasRole('admin'); $user->can('articles.delete'); $user->hasAnyRole(['admin', 'moderator']); . זה מבטיח שהרשאות מעודכנות ללא פגיעה בביצועים.
Middleware להגנת נתיבים:
Route::middleware(['role:admin'])->prefix('admin')->group(function () {
Route::resource('users', UserController::class);
});
Route::middleware(['permission:articles.create'])->group(function () {
Route::post('/articles', [ArticleController::class, 'store']);
});
Route::middleware(['role:admin|editor'])->group(function () {
Route::get('/articles/moderation', [ModerationController::class, 'index']);
}); איך ליישם ממשק ניהול תפקידים?
בנינו טופס React שבו המנהל רואה רשימת תפקידים עם ספירת הרשאות ויכול להקצות אותם למשתמשים דרך תיבות סימון. זה מקצר את זמן ניהול ההרשאות פי 3 בהשוואה לעריכה ידנית של מסד הנתונים.
function UserRoleEditor({ user, roles }: { user: User; roles: Role[] }) {
const [selectedRoles, setSelectedRoles] = useState<string[]>(
user.roles.map(r => r.name)
);
return (
<div>
{roles.map(role => (
<label key={role.id} className="flex items-center gap-2">
<input
type="checkbox"
checked={selectedRoles.includes(role.name)}
onChange={e => {
setSelectedRoles(prev =>
e.target.checked
? [...prev, role.name]
: prev.filter(r => r !== role.name)
);
}}
/>
<span>{role.name}</span>
<span className="text-sm text-gray-500">
({role.permissions.length} разрешений)
</span>
</label>
))}
</div>
);
} דוגמה לתפקידים והרשאות טיפוסיים
| תפקיד | הרשאות |
|---|---|
| מנהל | $this->authorize(), // Gates — простые проверки Gate::define('delete-article', function (User $user, Article $article) { return $user->hasRole('admin') || $article->author_id === $user->id; }); // Policy — для конкретной модели php artisan make:policy ArticlePolicy --model=Article class ArticlePolicy { public function update(User $user, Article $article): bool { return $user->can('articles.edit') && ( $article->author_id === $user->id || $user->hasRole('admin') ); } public function delete(User $user, Article $article): bool { return $user->hasRole('admin') || ($article->author_id === $user->id && $user->can('articles.delete')); } } // Использование в Controller public function update(Request $request, Article $article) { $this->authorize('update', $article); // ... } // В Blade @can('articles.create') <a href="/articles/create">Написать статью</a> @endcan , php artisan permission:cache-reset |
| עורך | Route::middleware(['role:admin'])->prefix('admin')->group(function () { Route::resource('users', UserController::class); }); Route::middleware(['permission:articles.create'])->group(function () { Route::post('/articles', [ArticleController::class, 'store']); }); Route::middleware(['role:admin|editor'])->group(function () { Route::get('/articles/moderation', [ModerationController::class, 'index']); }); , function UserRoleEditor({ user, roles }: { user: User; roles: Role[] }) { const [selectedRoles, setSelectedRoles] = useState<string[]>(user.roles.map(r => r.name)); return ( <div> {roles.map(role => ( <label key={role.id} className="flex items-center gap-2"> <input type="checkbox" checked={selectedRoles.includes(role.name)} onChange={e => { setSelectedRoles(prev => e.target.checked ? [...prev, role.name] : prev.filter(r => r !== role.name) ); }} /> <span>{role.name}</span> <span className="text-sm text-gray-500"> ({role.permissions.length} разрешений) </span> </label> ))} </div> ); } , users.manage |
| מנחה | articles.*, settings.* (רק משלו) |
| קורא | articles.create |
השוואת RBAC מול ABAC
| קריטריון | RBAC | ABAC |
|---|---|---|
| גמישות | בינונית — הרשאות קשורות בחוזקה לתפקידים | גבוהה — מתחשב במאפיינים (מחבר, תאריך, אזור) |
| ביצועים | מהיר יותר, מכיוון שהבדיקה נשמרת במטמון | יכול להיות איטי יותר עקב הערכת תנאים |
| פשטות | הגדרה קלה | מורכב יותר, דורש יותר לוגיקה |
| מתי לבחור | אתר טיפוסי עם 3–5 תפקידים | לוגיקת גישה מורכבת (למשל, multi-tenant) |
רשימת בדיקה של טעויות נפוצות
- שכחו לנקות את מטמון ההרשאות לאחר שינויים המוניים — הרשאות לא מתעדכנות.
- לא הגדירו Policy למודלים — בדיקות משוכפלות ב-controllers.
- שימוש ב-middleware רק בנתיבים אך לא בתוך controllers — פרצה אם מתודות נקראות ישירות.
- הקצאת הרשאות ישירות למשתמשים במקום לתפקידים — אובדן גמישות.
תהליך עבודה ולוח זמנים
- ניתוח: הגדרת תפקידים והרשאות עם הלקוח. יצירת מטריצת גישה.
- עיצוב: בחירת המודל (RBAC/ABAC), עיצוב סכמת מסד הנתונים.
- יישום: התקנת Spatie, יצירת תפקידים, הרשאות, Policies ו-middleware.
- ממשק: בניית ממשק ניהול תפקידים.
- בדיקות: בדיקת כל שילוב תפקידים לאיתור דליפות.
- פריסה: העלאה לשרת, ניקוי מטמון, הדרכת מנהלים.
הגדרת Spatie בסיסית עם 3 תפקידים ו-10 הרשאות אורכת 2–3 ימים. אם נדרשים ABAC ו-Policies מורכבים, עד 5 ימים. העלות מחושבת באופן אישי, בהתאם למספר התפקידים והאינטגרציות. התייעצו עם המהנדס שלנו כדי לבחור את מודל הגישה האופטימלי.
מה כלול
- תיעוד על תפקידים והרשאות
- קוד מקור עם הערות
- גישה לפאנל הניהול
- הדרכת מנהלים (שעה)
- חודש תמיכה
אם אתם רוצים להגן על האתר שלכם משגיאות גישה, צרו קשר לייעוץ — נעריך את הפרויקט שלכם ונציע את הפתרון הטוב ביותר. למהנדסים שלנו יש ניסיון של 10+ שנים ויישמו מעל 500 מערכות בקרת גישה. הזמינו הגדרת RBAC וקבלו ערובה לאבטחת המשאב שלכם.







