Gate::before реєструє колбек, який виконується перед усіма перевірками гейтів і політик. Поширений прийом - суперадміністратор, якому дозволено все:
Gate::before(function (User $user, string $ability) {
if ($user->isSuperAdmin()) {
return true;
}
});
Як працює результат:
true- дозвіл, жодні гейти й політики далі не викликаються;false- заборона, теж без подальших перевірок;null(нічого не повертати) - звичайна перевірка продовжується.
Пастки:
1. return false замість «нічого».
Gate::before(fn (User $user) => $user->isSuperAdmin()); // помилка!
Для звичайного користувача стрілкова функція повертає false - і всі перевірки в застосунку стають забороненими. Колбек має повертати true або null.
2. Суперадмін може «все» - справді все. true з before дозволяє і дії, які мали б бути заборонені для всіх за бізнес-правилами: видалити оплачене замовлення, змінити закритий фінансовий період, редагувати документ, підписаний іншою стороною. Якщо такі обмеження є, їх варто перевіряти поза гейтами (у сервісі, доменному об'єкті) або виключати в before:
Gate::before(function (User $user, string $ability) {
if ($user->isSuperAdmin() && ! in_array($ability, ['delete-paid-order', 'impersonate'], true)) {
return true;
}
});
3. Ризик облікового запису. Обліковий запис суперадміністратора - найцінніша мішень: обов'язкова двофакторна автентифікація, мінімум таких користувачів, журнал усіх дій.
4. Ознака «суперадміністратора» має бути надійною: поле в базі, яке не змінюється через масове призначення, а не email чи ім'я, що їх можна підробити в іншому контексті.
before у політиці - те саме, але лише для однієї моделі:
class PostPolicy
{
public function before(User $user, string $ability): ?bool
{
return $user->is_moderator ? true : null;
}
}
Особливість: метод before політики не викликається, якщо в політиці немає методу з назвою перевірюваної дії.
Gate::after - виконується після перевірки; його результат враховується, лише якщо основна перевірка повернула null. Зручно для аудиту рішень.
Тест, який варто мати: звичайний користувач отримує дозвіл на свої дії (захист від пастки з false) і відмову на чужі.
Докладніше в документації: Laravel: перехоплення перевірок гейтів