Модуль 22

Авторизація та permissions

Ось готовий урок, згенерований у стилі Девіда Малана (CS50) — енергійний, зрозумілий і сфокусований на суті.


🎓 Урок: Авторизація та Permissions (Дозволи)

Привіт, друзі! Це CS50 (умовно 😉), і сьогодні ми поговоримо про те, що перетворює звичайний сайт на безпечну фортецю.

1. 🔥 Вступ: «А ти хто такий?» проти «А що тобі можна?»

Уявіть, що ви прийшли на закриту вечірку в елітний нічний клуб. На вході стоїть охоронець. Ви показуєте йому паспорт. Він дивиться на фото, дивиться на вас і киває: «Окей, це ти, проходь».

Це — Автентифікація (Authentication). Ми зрозуміли, хто ви.

Але як тільки ви зайшли всередину, ви намагаєтеся пройти за діджейський пульт, щоб поставити свій улюблений трек. І тут інший охоронець каже: «Ей, стоп! Сюди не можна. Твій квиток — "Гість", а тут зона тільки для персоналу».

Ось це — Авторизація (Authorization). Ми знаємо, хто ви, але тепер вирішуємо, що вам дозволено робити.

❓ Риторичне питання: Якби авторизації не існувало, що завадило б вам видалити фотографії вашого друга в Instagram? Або переказати собі мільйон доларів з банківського рахунку Ілона Маска, просто знаючи номер його картки?

Чому без цього ніяк? У вебі (і в будь-якому софті) не можна довіряти нікому. Якщо ви не перевіряєте права доступу (Permissions), ваш додаток — це прохідний двір. Сьогодні ми навчимося ставити цих «цифрових охоронців».


2. 🧠 Теоретична база: Під капотом

Давайте розберемося з логікою. Не зазубрюйте терміни, зрозумійте процес.

Ключова відмінність (Запам'ятати обов'язково!)

  • Authentication (AuthN): Перевірка особи (Логін + Пароль). Відповідь на питання: "Ти хто?"
  • Authorization (AuthZ): Перевірка прав. Відповідь на питання: "Чи маєш ти право це робити?"

Як це працює «під капотом»?

Уявіть, що кожен користувач у вашій системі має невидимий рюкзак. Коли користувач (назвемо його User) намагається виконати дію (наприклад, delete_post), система робить таке:

  1. Заглядає в «рюкзак» користувача.
  2. Шукає там спеціальні позначки — Ролі (Roles) або Дозволи (Permissions).
  3. Порівнює їх із тим, що вимагає ця дія.

Модель RBAC (Role-Based Access Control) Це найпопулярніший підхід. Замість того, щоб кожному юзеру окремо прописувати "може редагувати", "може видаляти", ми даємо йому Роль.

  • Admin: Може все.
  • Editor: Може писати та редагувати статті.
  • Viewer: Може тільки читати.

Логіка проста: IF user.role == 'Admin' THEN allow()


3. 🧪 Приклади (Код + Логіка)

Давайте подивимося на код. Я використовуватиму псевдокод, схожий на Python, бо він читається як англійська.

Приклад 1: Найпростіша перевірка (Hard check)

Уявіть, що у нас є функція видалення коментаря.

❓ Питання до вас: Що станеться, якщо я викличу цю функцію від імені звичайного користувача, але забуду додати перевірку? (Спойлер: Хаос. Будь-хто видалить що завгодно).

Ось як це робиться правильно:

def delete_comment(user, comment):
    # Спочатку перевіряємо роль
    if user.role == "admin":
        comment.delete()
        print("Коментар видалено адміністратором.")
    else:
        print("Помилка! У вас недостатньо прав.")

Результат: Якщо user.role це "guest", код піде в гілку else. Система захищена.


Приклад 2: "Це моє!" (Ownership)

Але чекайте. В Instagram ви не адмін, але ви можете видалити свій коментар. Як це працює? Тут перевірка ролі не допоможе. Треба перевірити авторство.

❓ Очікування: Як ми дізнаємося, що коментар належить саме цьому юзеру? (Ми повинні порівняти ID автора коментаря з ID поточного юзера).

def delete_own_comment(current_user, comment):
    # Логіка: Або ти адмін, АБО це твій коментар
    if current_user.role == "admin" or comment.author_id == current_user.id:
        comment.delete()
        print("Успіх! Видалено.")
    else:
        print("Гей! Не чіпай чуже.")

Бачите? Ми комбінуємо умови. Це і є суть політик доступу.


Приклад 3: Декоратори (Рівень PRO)

У реальних проєктах (Flask, Django, FastAPI) ми не пишемо if у кожній функції. Це брудний код. Ми використовуємо декоратори — це як наклейка на двері "Тільки для персоналу".

@requires_role("admin")
def nuke_database():
    print("Базу даних знищено!")

# Якщо це спробує викликати студент:
# Система перехопить виклик ДО виконання функції і викине помилку 403 Forbidden.

4. 🛠 Практична частина

Час закотити рукави! Виконайте ці завдання (у голові або в редакторі коду):

  1. 🔹 Повторення: Напишіть функцію edit_article(user, article), яка дозволяє редагування тільки якщо user.role дорівнює "editor".
  2. 🔹 Зміна умов: Модифікуйте функцію з п.1. Тепер редагувати може "editor", АЛЕ тільки якщо стаття ще не опублікована (article.is_published == False). Адмін може редагувати завжди.
  3. 🔹 Виправ помилку: python def view_premium_content(user): if user.subscription_status = "active": # <-- Що тут не так синтаксично і логічно? show_video()
  4. 🔹 Міні-кейс: Уявіть Google Docs.

    • Є Owner (власник файлу).
    • Є Editor (той, кому дали доступ на редагування).
    • Є Viewer (тільки перегляд).
    • Напишіть псевдокод для функції change_title(user, doc), яка дозволяє змінювати назву документа. Хто має на це право? (Тільки Owner чи Editor теж? Вирішувати вам, але обґрунтуйте).
  5. 🔹 Питання «А що, якщо...»: Що, якщо ми перевіряємо права тільки на фронтенді (в JavaScript)? Я сховав кнопку "Видалити" для звичайного юзера. Чи це безпечно? (Підказка: згадайте про Postman або curl).


5. 💡 Мислення як у розробника

Як відрізнити новачка від профі?

❌ Помилка новачка: «Я сховав кнопку в інтерфейсі, значить користувач не може це натиснути». Реальність: Хакери не користуються вашим інтерфейсом. Вони надсилають запити напряму на сервер. Завжди перевіряйте права на сервері (Back-end)!

❌ Помилка новачка: Хардкод ID. if user.id == 5: allow(). Реальність: А якщо користувача з ID 5 видалять? Або це буде інша людина в іншій базі даних? Використовуйте ролі або прапорці (is_superuser).

🧠 Як думає сеньйор: Принцип "Deny by Default" (Заборонено за замовчуванням). Ми не пишемо: «Дозволити Петру, Марії та адміну». Ми пишемо: «Заборонити всім. А тепер, як виняток, дозволити адміну». Це набагато безпечніше. Якщо ви забудете прописати правило, доступ просто ніхто не отримає (це краще, ніж отримають усі).


6. 🧩 Підсумок

Отже, що ми сьогодні зробили: 1. Зрозуміли різницю: Автентифікація — це паспорт, Авторизація — це квиток. 2. Розібрали RBAC (ролі) та перевірку авторства. 3. Навчилися захищати функції від «лівих» користувачів.

Тепер ви вмієте: Не просто пускати людей на сайт, а контролювати кожен їхній крок. Ви стали архітектором безпеки свого додатку.

🕵️‍♂️ Тизер наступного уроку: Окей, ми дозволили юзеру редагувати статтю. Але що, якщо замість тексту статті він відправить шкідливий скрипт, який зламає браузери іншим читачам? На наступному уроці ми поговоримо про Валідацію даних та Санітизацію.

А поки — це був CS50. Побачимось! 👋