Модуль 29

Basic auth та захист адмін-зон

Ось готовий урок, написаний у стилі Девіда Малана: енергійно, з фокусом на розуміння суті («чому?»), а не просто зазубрювання коду.


🎓 CS50-style: Basic Auth та захист адмін-зон

Привіт, друзі! Радий бачити вас. Сьогодні ми поговоримо про безпеку. Але не про ту складну кібербезпеку з фільмів про хакерів у худі, а про базову гігієну вашого веб-застосунку.

1. 🔥 Вступ: Проблема відчинених дверей

Уявіть ситуацію. Ви створили свій власний блог або інтернет-магазин. Ви працювали ночами, писали код, і нарешті запустили проєкт. У вас є спеціальна сторінка — скажімо, /admin, де ви можете видаляти коментарі, банити користувачів або змінювати ціни.

Ви знаєте цю адресу. Але що заважає комусь іншому — випадковому відвідувачу або конкуренту — просто дописати в адресному рядку /admin і натиснути Enter?

Риторичне питання: Якщо ви не повісили замок на двері свого будинку, чи здивуєтесь ви, якщо вранці знайдете на кухні незнайомця, який п'є вашу каву?

В Інтернеті так само. Якщо маршрут існує, хтось на нього зайде.

Чому без цього не обійтись? Ви не можете будувати жодну серйозну систему, якщо будь-хто може керувати нею. Нам потрібен спосіб сказати серверу: "Гей, це я, власник. Пусти мене, а інших — ні".

Сьогодні ми розберемо найпростіший, найстаріший, але досі актуальний спосіб це зробити — HTTP Basic Authentication.


2. 🧠 Теоретична база: Як це працює «під капотом»

Давайте розвіємо магію. Веб (HTTP) — це протокол без збереження стану (stateless). Це означає, що сервер має "коротку пам'ять". Кожен ваш запит для нього — як перший.

Тому, щоб потрапити в адмінку, ви повинні з кожним запитом передавати "перепустку".

Як виглядає Basic Auth?

Уявіть, що ви підходите до охоронця (сервера). 1. Ви кажете: "Хочу в /admin". 2. Охоронець: "Хто ти? Покажи документи". (Повертає статус 401 Unauthorized). 3. Браузер показує вам віконце для введення логіна і пароля. 4. Ви вводите: admin / 12345. 5. Браузер бере ці дані, склеює їх через двокрапку (admin:12345) і кодує у формат Base64. 6. Виходить рядок типу YWRtaW46MTIzNDU=. 7. Браузер відправляє цей рядок у заголовку (Header) запиту.

⚠️ Обовʼязково запам’ятати: * Base64 — це НЕ шифрування! Це просто спосіб записати дані іншими символами. Будь-хто, хто перехопить цей рядок, може розкодувати його назад у admin:12345 за мілісекунду. * Саме тому Basic Auth можна використовувати ТІЛЬКИ разом з HTTPS. HTTPS створює захищений тунель, щоб ніхто не підгледів ваш Base64-рядок.

Інтуїтивне розуміння: Basic Auth — це як написати пароль на папірці і показати його через броньоване скло (HTTPS). Якщо скла немає (HTTP), ви просто кричите пароль на всю вулицю.


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

Приклад 1: Як це бачить браузер (Raw HTTP)

Давайте подивимось, що насправді літає по мережі.

Запит без авторизації:

GET /admin HTTP/1.1
Host: mywebsite.com

Відповідь сервера (Ти не пройдеш!):

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Admin Zone"

(Цей заголовок WWW-Authenticate змушує браузер показати вам спливаюче вікно для введення пароля).

Ваш повторний запит (З перепусткою):

GET /admin HTTP/1.1
Host: mywebsite.com
Authorization: Basic YWRtaW46MTIzNDU=

Приклад 2: Реалізація в коді (Python / Pseudo-code)

Як би це виглядало, якби ми писали перевірку вручну?

def handle_request(request):
    # 1. Отримуємо заголовок
    auth_header = request.headers.get('Authorization') 

    # Якщо заголовка немає — відмовляємо
    if not auth_header:
        return Response(status=401, headers={'WWW-Authenticate': 'Basic realm="Login Required"'})

    # 2. Розбираємо заголовок (він приходить як "Basic <код>")
    token = auth_header.split(" ")[1] 

    # 3. Декодуємо Base64
    decoded_str = base64_decode(token) # отримуємо "admin:supersecret"
    username, password = decoded_str.split(":")

    # 4. Звіряємо з нашою базою
    if username == "admin" and password == "supersecret":
        return "Ласкаво просимо в адмінку! 🚀"
    else:
        return Response(status=403, body="Невірний пароль!")

Питання до вас: Чому ми перевіряємо це на сервері, а не на клієнті (в JavaScript)? (Пауза на подумати) Відповідь: Тому що код на клієнті може подивитися будь-хто. "Секрет", який лежить у браузері користувача — це вже не секрет.


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

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

  1. 🔹 Ручна робота: Візьміть рядок user:password і знайдіть онлайн-конвертер у Base64. Закодуйте його. Тепер розкодуйте назад. Переконайтеся, що це не магія, а просто кодування.

  2. 🔹 Симулятор сервера: Напишіть функцію (на будь-якій мові: Python, JS, PHP), яка приймає рядок Basic dXNlcjpwYXNz і повертає True, якщо логін — "admin", а пароль — "1234", і False у всіх інших випадках.

  3. 🔹 Пошук вразливості: У вас є сайт на http:// (без S). Ви налаштували Basic Auth. Ви сидите в кав'ярні з відкритим Wi-Fi. Завдання: Опишіть сценарій, як зловмисник, що сидить за сусіднім столиком, отримає доступ до вашої адмінки.

  4. 🔹 Міні-кейс: Вам потрібно тимчасово закрити доступ до сайту, який ще в розробці (staging), від очей Google та випадкових користувачів. Чому Basic Auth тут — ідеальне рішення, краще за складну систему реєстрації?

  5. 🔹 А що, якщо... Що станеться, якщо ви зміните пароль на сервері, поки користувач переглядає адмінку? Чи викине його з системи одразу при наступному кліку? (Спойлер: так. Чому? Згадайте про "пам'ять" сервера).


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

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

❌ Помилка новачка: Використовувати Basic Auth для звичайних користувачів (клієнтів магазину). * Чому це погано: Браузер запам'ятовує цей логін/пароль намертво, поки ви його не закриєте. Зробити кнопку "Вийти" (Log out) при Basic Auth дуже складно і "милижно". Інтерфейс виглядає застарілим.

✅ Як думає профі: Basic Auth — це інструмент для технічних задач: 1. Закрити тестову версію сайту (staging). 2. Захистити просту адмінку для внутрішнього користування. 3. Автентифікація між мікросервісами (коли один бот стукає до іншого).

Порада з практики: Ніколи не зберігайте паролі в коді (hardcode). * Погано: if password == "mysecret" * Добре: if password == os.getenv("ADMIN_PASSWORD") Зчитуйте їх зі змінних оточення. Інакше ви випадково заллєте пароль на GitHub, і тоді Basic Auth вас не врятує.


6. 🧩 Підсумок

Отже, що ми маємо в сухому залишку?

  1. Basic Auth — це простий спосіб захисту, де логін і пароль літають у кожному запиті в заголовку.
  2. Це Base64, а не шифрування. Без HTTPS це все одно, що кричати пароль у рупор.
  3. Це ідеально для адмін-зон та тестових середовищ, але погано для звичайних користувачів через слабкий UX.

Тепер ви вмієте: Замикати двері свого веб-додатку на простий, але надійний замок.

🔍 Тизер наступного уроку: Але що, якщо у нас мільйон користувачів? Ми ж не будемо змушувати кожного вводити пароль при кожному кліку, правда? І ми хочемо красиву кнопку "Вийти". Для цього нам знадобиться дещо розумніше за просте пред'явлення паспорта. На наступному занятті ми поговоримо про Cookies, Sessions та Tokens.

А поки що — бережіть свої дані! Це був CS50.