Завантаження публікації
ОГОЛОШЕННЯ

Тести на доступи в Laravel: перевіряємо “хто що може” і не ловимо витоки після правок

Практична методика для адмінки: як тестувати middleware permissions та Policies/Gates, як перевіряти 403/404 на чужі записи, і як гарантувати, що фільтри та update не дають підвищити права через підсунуті поля.


Максим Третяк
Максим Третяк
Газета Дейком | 02.01.2026, 16:00 GMT+3; 09:00 GMT-4

Тести на доступи — це єдине, що реально страхує вас від “випадково відкрили зайве” після змін у коді. У проєктах з ролями, approval-статусами і модулями типу “контроль публікацій” ризик завжди один: хтось додав новий маршрут, змінив фільтр, підвантажив зв’язок або “спростив” update, і в результаті користувач бачить/змінює те, що не повинен. Тому доступи тестують не як “один тест на все”, а як набір коротких сценаріїв: доступ до розділу, доступ до конкретного запису, доступ до дії, і захист від підміни полів.

Є два рівні тестів на доступи, які вам потрібні. Перший — інтеграційні (feature): реальний HTTP-запит на маршрут і перевірка статусу 200/302/403/404. Це перевіряє middleware, політики і контролери разом. Другий — unit/authorization-тести (опційно): прямі перевірки policy-методів (can/cannot) для конкретних комбінацій користувача й запису. У вашому випадку критичні саме feature-тести, бо у вас є middleware permissions, і головні збої трапляються на рівні маршруту/фільтрів.

Починайте з матриці ролей. Не треба писати всі комбінації одразу, але треба визначити мінімум 3–4 “актори”, які реально відрізняються правами. Наприклад: гість (не авторизований), автор (бачить/редагує своє), редактор (бачить ширше, може approve/publish), адміністратор (може все). Далі для кожного модуля визначаєте ключові дії: viewAny (список), view (перегляд), create, update, delete, і 1–2 кастомні (approve/publish). Саме під ці дії і пишуться тести.

Перший базовий блок — “вхід у модуль”. Це перевірка middleware permissions. Тут тест простий: актор без права отримує 403 (або редирект на логін, якщо гість), актор з правом отримує 200. Це гарантує, що ви не забули повісити middleware на новий маршрут або групу. Важливий момент: якщо у вас прийнято “ховати існування” і віддавати 404 замість 403 — тестуйте 404. Головне, щоб поведінка була стабільна.

Другий блок — “доступ до конкретного запису”. Це те, що найчастіше ламається через неправильні запити. Наприклад, автор має бачити тільки свої записи. Тест будується так: створюєте два записи — один належить автору, другий — іншому. Далі перевіряєте: для чужого запису edit/show має бути 403 або 404. Це ключовий тест, який ловить витоки через прямий підбір ID.

Третій блок — “доступ до дії”. Тут важливо не плутати “бачити форму” і “виконати дію”. Наприклад, кнопка може бути схована в UI, але користувач може відправити POST/PUT вручну. Тому завжди тестуйте саме endpoint: POST store, PUT update, DELETE destroy, POST approve тощо. Очікування: без прав — 403/404; з правами — 302 редирект і зміни в базі.

Четвертий блок — “захист від підміни полів”. Це найбільш підступна частина. У вас можуть бути поля, які не можна міняти звичайному редактору або автору: approval_status, subscription_required, created_by, billing_entity_id, фінансові суми, ознаки “оплачено”. Людина може підставити ці поля у форму або в запит. Навіть якщо policy дозволяє update тексту, сервіс повинен ігнорувати заборонені поля або відмовляти. Це тестується так: відправляєте update з дозволеним полем плюс забороненим, і перевіряєте, що дозволене оновилось, а заборонене — ні. Це реальний “анти-ескалаційний” тест, який рятує від найнеприємніших інцидентів.

П’ятий блок — “фільтри не розширюють доступ”. Якщо у вас є query string фільтри (user_id, status, date range), їх можна використати як інструмент витоку, якщо базове обмеження видимості накладено неправильно. Тест простий: актор з обмеженою видимістю викликає index з параметрами, які “просять” чужі записи, і перевіряє, що чужі записи не з’явились у відповіді. Це підтверджує, що ви спочатку обмежуєте по доступах, а потім застосовуєте фільтри.

Практичні статус-коди. 302 — це успішний POST/PUT/DELETE з редиректом на список. 200 — успішний перегляд. 403 — “заборонено”. 404 — “не знайдено”, коли ви ховаєте існування чужих записів, або коли вибірка йде через “доступний scope” і чужий запис просто не знаходиться. Важливо вибрати одну політику і тримати її консистентно, інакше тести будуть “плавати”, а система — поводитись непередбачувано.

Як організувати тести по файлах. Найзручніше робити по модулю: tests/Feature/Admin/NewsAccessTest.php, TagAccessTest.php, InvoiceAccessTest.php. Усередині — групи тестів по діях. Для читабельності використовуйте helper-методи: makeAuthor(), makeEditor(), grantPermissions(), createNewsOwnedBy($user). Це зменшує шум і робить тести підтримуваними.

Як зробити “актора з правами” у вашому контексті. Оскільки у вас permission middleware критичний, у тестах треба вміти видати користувачу потрібні права так само, як у проді: або через таблицю permissions/roles, або через ваші seeders. Найправильніше — мати маленький helper, який додає конкретний permission, наприклад news.view, news.update, news.approve. Якщо фабрик немає, користувачів створюєте руками. Головне — не вимикати middleware в тестах, бо тоді ви тестуєте не те, що працює в реальності.

Мінімальний “must-have” набір тестів на доступи для одного CRUD-модуля виглядає так. Гість не має доступу до index (редирект/403). Користувач без права не має доступу до index (403). Користувач з правом має доступ до index (200). Користувач не може редагувати чужий запис (403/404). Користувач з правом може створити запис (302 + запис у БД). Користувач без права не може видалити (403/404). І один тест на підмішування забороненого поля в update (поле не змінилось). Це 6–8 тестів, які дають максимальну віддачу за мінімум коду.

Висновок: тести на доступи — це ваш страховий механізм від найнеприємнішого класу багів: витоків і ескалації прав. Тестуйте доступ до модулів (middleware), доступ до конкретних записів (policy + вибірка), доступ до дій (POST/PUT/DELETE), і обов’язково підміну полів в update. Якщо ці тести є, ви можете сміливіше рефакторити, додавати фільтри і нові екрани, не боячись, що “десь відкрили зайве” або “хтось змінив статус без прав”.


Максим Третяк — Кореспондент, який спеціалізується на суспільно важливих темах, пише про політику, фінансові ринки та економіку. Він проживає та працює в Україні.

Цей матеріал є частиною розгорнутої теми: Web-програмування, яка охоплює численні цікаві аспекти цієї події. Газета «Дейком» ретельно відстежує події, проводячи перевірку джерел та інформації, щоб забезпечити нашим читачам найбільш точне та актуальне інформування.

Цей матеріал опубліковано 02.01.2026 року о 16:00 GMT+3 Київ; 09:00 GMT-4 Вашингтон, розділ: Освіта, із заголовком: "Тести на доступи в Laravel: перевіряємо “хто що може” і не ловимо витоки після правок". Якщо в публікації з'являться зміни, про це буде зазначено та описано у кінці публікації.

Читайте щоденну газету та загальну стрічку новин газети Дейком, яка поєднує багато цікавого в понад 40 розділах з усіх куточків світу.


Save
ОГОЛОШЕННЯ

Новини, які можуть Вас зацікавити:

Штатні та позаштатні журналісти газети «Дейком» щодня готують сотні публікацій, щоб читачі отримували найоперативнішу, перевірену й глибоку інформацію. Ми працюємо для тих, хто хоче розуміти суть подій, бачити широку картину та бути на крок попереду.

Останні новини

Вибір редакції