Модуль 28

Авторизація і ролі користувачів

Ось твій урок у стилі CS50! 🚀


🎓 CS50: Авторизація і ролі користувачів

(Або: Чому наявність перепустки не означає, що вам можна в кабінет директора)


1. 🔥 Вступ: проблема та мотивація

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

Ви всередині. Але чи означає це, що ви можете вийти на сцену, взяти мікрофон і почати співати замість артиста? Чи можете ви зайти в гримерку до зірок? Звісно, ні. Ваш квиток — це звичайний вхід. А у звукорежисера — бейдж "Staff". А у артиста — бейдж "VIP/Artist".

У світі веб-розробки це працює так само. Минулого разу ми говорили про Аутентифікацію (Authentication) — це процес відповіді на питання "Хто ти?" (сканування квитка на вході).

Але сьогодні ми говоримо про Авторизацію (Authorization). Це відповідь на питання: "А що тобі, власне, можна тут робити?".

Риторичне запитання: Уявіть, що було б, якби в банківському додатку ви увійшли під своїм логіном, але система не перевірила ваші права і дозволила вам переказати гроші з рахунку Ілона Маска? Хаос, правда?

Ось чому без теми ролей та прав доступу (Authorization) не існує жодного серйозного сервісу — від Instagram до "Дії".


2. 🧠 Теоретична база (без сухої академічності)

Давайте розкладемо це по поличках.

Головна формула:

AuthN (Аутентифікація) = Хто ти? (Логін/Пароль) AuthZ (Авторизація) = Що тобі дозволено? (Права/Ролі)

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

Коли сервер отримує запит від користувача (наприклад, "Видалити цей коментар"), він робить дві перевірки:

  1. Check 1: Чи залогінений цей користувач? (Так, це користувач ivan_99).
  2. Check 2: Чи має ivan_99 право видаляти коментарі?

Тут в гру вступають Ролі (Roles).

Уявіть собі табличку в Excel або базі даних. У кожного користувача є колонка role. * Guest (Гість): Тільки перегляд. * User (Користувач): Може писати свої пости, редагувати свої дані. * Admin (Адмін): Бог системи. Може видалити будь-кого.

❗️ Що треба запам’ятати залізно: Ніколи, чуєте, НІКОЛИ не довіряйте інтерфейсу. Те, що ви приховали кнопку "Видалити" на сайті для звичайного юзера, не означає, що він не може відправити запит на видалення через код. Перевірка завжди має бути на сервері.


3. 🧪 Приклади (від простого до реального)

Давайте подивимось на код. Я буду використовувати псевдокод, схожий на Python/JavaScript, щоб було зрозуміло всім.

Приклад 1: Наївний підхід (Як не треба, але з чого починають)

Ви хочете дати доступ до секретної сторінки тільки одному користувачу.

def delete_database(user):
    # Якщо користувача звати "admin", дозволяємо
    if user.username == "admin":
        return "Базу даних видалено! 💥"
    else:
        return "Помилка: У вас немає прав!"

Питання до вас: Що станеться, якщо адмін вирішить змінити свій нікнейм на "SuperAdmin"? Відповідь: Система зламається. Ніхто не зможе видалити базу. Прив'язуватись до імен — погана ідея.


Приклад 2: Role-Based Access Control (RBAC) — Класика

Додамо користувачу властивість role.

# Уявимо, що об'єкт user виглядає так:
# user = { id: 1, username: "ivan", role: "moderator" }

def delete_comment(user, comment_id):
    # Перевіряємо роль
    allowed_roles = ["admin", "moderator"]

    if user.role in allowed_roles:
        execute_delete(comment_id)
        return "Коментар видалено."
    else:
        return "Доступ заборонено ⛔️"

Чому це краще? Ми можемо мати 100 модераторів, і код працюватиме для всіх. Нам не треба знати їхні імена.


Приклад 3: Вищий пілотаж (Власність ресурсів)

Ситуація: Користувач хоче відредагувати свій профіль. Він не адмін і не модератор. Він просто "user". Але він має право редагувати себе, але не інших.

Питання: Як перевірити це?

def edit_profile(current_user, target_profile_id):
    # 1. Якщо це адмін — можна все
    if current_user.role == "admin":
        return save_changes()

    # 2. Якщо користувач редагує сам себе
    if current_user.id == target_profile_id:
        return save_changes()

    # В усіх інших випадках
    return "Гей, це не твій профіль! 😡"

Це називається перевіркою власності (Ownership). Це критично важливо для соціальних мереж.


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

Час "забруднити руки" кодом! Виконайте ці завдання подумки або у своєму редакторі.

🔹 Завдання 1: Фейс-контроль Напишіть функцію can_view_dashboard(user), яка повертає True, тільки якщо роль користувача — "admin" або "manager". Для всіх інших — False.

🔹 Завдання 2: Зміна умов Додайте в попередню функцію умову: якщо користувач "banned" (має прапорець is_banned = True), то йому заборонено вхід, навіть якщо він "admin". (Так, адмінів теж банять!).

🔹 Завдання 3: "Дірка" в безпеці У коді нижче є логічна помилка. Знайдіть її.

def give_bonus(user):
    if user.role != "intern":  # Якщо не стажер
        send_money(1000)
    else:
        print("Вибач, стажере.")

(Підказка: А що, якщо роль користувача — "hacker" або "guest"? Чи отримають вони гроші? Як це виправити, використовуючи принцип "білого списку"?)

🔹 Завдання 4: Міні-кейс Ви робите систему для Школи. Є ролі: Teacher, Student, Principal. Хто має доступ до функції change_grade(student_id, new_grade)? 1. Директор (Principal)? 2. Вчитель (Teacher)? 3. Студент (Student)? Опишіть логіку перевірки.

🔹 Питання "А що, якщо..." Що, якщо користувач має одразу дві ролі? Наприклад, він і Teacher, і Parent (мама учня в тій же школі). Як би ви зберігали ролі в базі даних? (Один рядок чи список?)


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

Як думає досвідчений інженер, коли проектує систему доступу?

  1. Принцип найменших привілеїв (Least Privilege).

    • Новачок: "Дам усім права адміна, щоб точно все працювало, а потім заберу зайве".
    • Профі: "За замовчуванням — ЗАБОРОНЕНО ВСЕ. Я буду видавати права тільки по краплинці, і тільки ті, що необхідні для роботи".
  2. Безпека на бекенді, зручність на фронтенді. Якщо ви приховали кнопку в HTML — це для краси. Якщо ви поставили if у контролері на сервері — це для безпеки. Хакери не користуються браузером, вони шлють запити напряму через термінал (cURL / Postman).

  3. Не вигадуйте велосипед. У більшості фреймворків (Django, Spring, Laravel, .NET) системи ролей вже вбудовані. Вивчіть їх, перш ніж писати свої милиці.


6. 🧩 Підсумок

Отже, що ми сьогодні зрозуміли: * Аутентифікація — це паспорт (Хто ти?). * Авторизація — це ключі від дверей (Куди тобі можна?). * Ми навчилися перевіряти ролі (if user.role == 'admin'). * Ми зрозуміли, що перевіряти треба не тільки "хто ти", а й "чиє це" (власність ресурсу).

Тепер ви вмієте: Розділяти користувачів на класи і захищати чутливі дані від "зайвих очей".

🕵️‍♀️ Тизер наступного уроку: Окей, ми перевірили пароль, ми перевірили роль. Але де зберігати цей стан, щоб користувачу не доводилось вводити пароль при кожному кліку мишкою? Наступного разу ми поговоримо про Сесії, Куки (Cookies) та JWT токени. Готуйтеся, буде смачно! 🍪


Це був CS50. Побачимось! 👋