Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Чим гейти відрізняються від політик у Laravel і як захистити маршрут через can?

Гейти (gates) - замикання для дій, не прив'язаних до конкретної моделі:

// AppServiceProvider::boot()
Gate::define('view-reports', fn (User $user) => $user->hasRole('analyst'));
Gate::define('access-admin', fn (User $user) => $user->is_admin);

Політики (policies) - клас з правилами для однієї моделі:

php artisan make:policy PostPolicy --model=Post
class PostPolicy
{
    public function update(User $user, Post $post): bool
    {
        return $user->id === $post->author_id;
    }

    public function delete(User $user, Post $post): bool
    {
        return $user->id === $post->author_id || $user->is_moderator;
    }
}

Laravel знаходить політику за назвою (App\Models\Post → App\Policies\PostPolicy) або за атрибутом на моделі.

Як перевіряти:

// у контролері
Gate::authorize('update', $post);           // 403, якщо заборонено
if ($request->user()->cannot('delete', $post)) { abort(403); }

// у Blade - лише для відображення
@can('update', $post) <a href="...">Редагувати</a> @endcan

// у Form Request
public function authorize(): bool { return $this->user()->can('update', $this->route('post')); }

На маршрутах - middleware can:

Route::put('/posts/{post}', [PostController::class, 'update'])->can('update', 'post');
Route::get('/admin/reports', ReportController::class)->middleware('can:view-reports');
Route::post('/posts', [PostController::class, 'store'])->can('create', Post::class);

'post' - назва параметра маршруту: після прив'язки моделі в політику потрапить конкретний пост. Для дій без екземпляра (create) передається клас.

Що обрати:

  • політика - для всього, що стосується моделі (CRUD і власні дії). Логіка доступу до сутності - в одному місці;
  • гейт - для загальних можливостей (доступ до адмінки, звітів, функцій тарифу).

Пастки:

  • @can у шаблоні лише ховає кнопку - перевірка на сервері (контролер, маршрут) обов'язкова;
  • методи політики повинні повертати bool (або Response): забутий return дає null - і доступ заборонено, що безпечно, але збиває з пантелику;
  • гості: для неавтентифікованого користувача гейти й політики за замовчуванням повертають false, якщо параметр користувача не оголошено як ?User.

Докладніше в документації: Laravel: авторизація через middleware

Схожі питання