Ось готовий урок, створений за твоїм майстер-промптом.
🎓 CS50-Style: JWT та Token Authentication
Привіт, друзі! 👋 Це CS50 (умовно 😉), і сьогодні ми розберемо тему, яка є кровоносною системою 99% сучасних веб-додатків.
1. 🔥 Вступ: Проблема «Амнезії» Сервера
Уявіть собі таку ситуацію. Ви приходите у великий бізнес-центр. На вході суворий охоронець запитує ваш паспорт, перевіряє його в базі даних і пропускає вас. Ви підходите до ліфта — там інший охоронець знову вимагає паспорт. Виходите на поверсі — знову перевірка. Хочете зайти в туалет — і там перевіряють паспорт!
Звучить як пекло, правда? Але саме так працює протокол HTTP.
HTTP — це протокол без стану (stateless). Це означає, що сервер має «амнезію». Коли ви відправляєте запит №2, він поняття не має, що запит №1 теж був від вас.
Риторичне запитання: Як зробити так, щоб ви один раз ввели логін/пароль, а далі сервер впізнавав вас автоматично, не запитуючи пароль при кожному кліку?
Раніше ми використовували сесії (Sessions). Це як запис у журналі охоронця: "Ага, Іван зайшов о 9:00, ось його ID". Але якщо у вас мільйон користувачів, цей журнал стає велетенським. А якщо у вас 10 серверів (охоронців)? Їм доведеться постійно перегукуватися між собою: "Ей, ти бачив Івана?".
Нам потрібен кращий спосіб. Нам потрібен JWT (JSON Web Token).
Уявіть фестивальний браслет. Ви один раз показуєте квиток на вході, вам чіпляють браслет. Все! Тепер будь-який охоронець на будь-якій сцені бачить браслет і знає: "Цьому хлопцю можна сюди". Йому не треба дзвонити на головний вхід. Ваші права доступу — прямо на вашій руці.
2. 🧠 Теоретична база: Що там «під капотом»?
Давайте розберемося, що таке JWT (вимовляється як "джот").
JWT — це відкритий стандарт передачі даних між клієнтом (браузером) і сервером у вигляді JSON-об'єкта. Але не простого, а підписаного.
Анатомія Токена
Якщо ви подивитеся на JWT, він виглядає як довгий рядок літер і цифр, розділених двома крапками.
aaaaa.bbbbb.ccccc
Він складається з трьох частин:
- 🔴 Header (Заголовок): Який алгоритм шифрування використовується (наприклад, HS256). Це "метадані".
- 🟣 Payload (Корисне навантаження): Самі дані. Наприклад:
{"userId": 123, "role": "admin"}. - 🔵 Signature (Підпис): Це найважливіше! Це гарантія того, що дані не змінили.
Як працює магія (Інтуїтивно)
Уявіть, що ви відправляєте прозору скриньку з листом. * Header & Payload — це сам лист. Його може прочитати кожен (так-так, це важливо!). * Signature — це сургучева печатка на скриньці, яку поставив сервер своїм унікальним штампом (Secret Key).
Якщо хакер перехопить скриньку і змінить у листі "role": "user" на "role": "admin", то стара печатка вже не підійде до нового змісту (математично не зійдеться). А нову печатку хакер поставити не зможе, бо у нього немає унікального штампа (Secret Key), який є тільки у сервера.
❗️ Запам’ятати обов'язково: JWT не шифрує дані (за замовчуванням). Він їх підписує. Будь-хто, хто перехопив токен, може прочитати, що всередині. Тому ніколи не пхайте туди паролі!
3. 🧪 Приклади: Від простого до реального
Приклад 1: Сирий вигляд
Ви логінитесь у систему. Сервер перевірив пароль і віддав вам це:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Питання до вас: Що ви очікуєте побачити, якщо ми розкодуємо середню частину (після першої крапки)?
Давайте перевіримо. Це звичайний Base64 (спосіб кодування тексту). Всередині там:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
sub(subject) — ID користувача.iat(issued at) — коли токен видали.
Приклад 2: Процес авторизації (Flow)
Як це виглядає у реальному житті веб-додатку:
- Клієнт: Відправляє POST запит
/loginзloginтаpassword. - Сервер: Перевіряє базу. Все ок? Генерує JWT (бере ID юзера + Секретний ключ = Токен).
- Сервер: Віддає токен клієнту.
- Клієнт: Зберігає токен (наприклад, у LocalStorage).
- Клієнт: Хоче отримати список замовлень. Робить запит GET
/orders. Але! У заголовок запиту додає:Authorization: Bearer <TOKEN>. - Сервер: Бачить токен. Перевіряє підпис (Signature) своїм ключем. Підпис валідний? Токен не прострочений? Ок, ось твої замовлення. Базу даних для перевірки логіна чіпати не треба!
4. 🛠 Практична частина
Час забруднити руки! Виконайте ці завдання, щоб закріпити матеріал.
Завдання 1: Хірург токенів
Зайдіть на сайт jwt.io. Це головний інструмент розробника для роботи з JWT.
1. Подивіться на дефолтний токен.
2. У правій частині (Payload) змініть ім'я John Doe на своє ім'я.
3. Подивіться ліворуч: Що змінилося в зашифрованому рядку? Тільки середина чи й кінець? Чому?
Завдання 2: "Хакерська атака"
Уявіть, що ви — сервер. Ваш секретний ключ: "mySuperSecretKey".
Використовуючи будь-яку онлайн-утиліту HMAC-SHA256 (або Node.js), спробуйте створити валідний підпис для даних {"user": "admin"}.
Завдання 3: Реалізація (Node.js псевдокод)
Вставте пропущені рядки в цей код:
const jwt = require('jsonwebtoken');
// 1. Користувач успішно ввів пароль
const user = { id: 55, username: "david_malan" };
// 2. Створення токена
// ПІДКАЗКА: нам потрібен user, секретний ключ і час життя токена
const token = jwt.sign(__________, 'SECRET_KEY', { expiresIn: '1h' });
console.log("Ваш токен:", token);
// 3. Перевірка токена (коли користувач повернувся)
try {
const decoded = jwt.verify(token, __________);
console.log("Ласкаво просимо,", decoded.username);
} catch(err) {
console.log("Хто ти такий? Токен недійсний!");
}
Завдання 4: Міні-кейс
Ви створюєте додаток для банку. Чи безпечно передавати в Payload токена номер кредитної картки користувача? * А) Так, бо токен підписаний. * Б) Ні, бо Base64 легко розкодувати. * Обґрунтуйте відповідь.
5. 💡 Мислення як у розробника
Ось що відрізняє джуніора від сеньйора в темі JWT:
1. "Безсмертні" токени — це зло. Новачки часто роблять токени, які живуть вічно. Якщо хакер вкраде такий токен, він матиме доступ до акаунту назавжди. * Як думає про: Токен доступу (Access Token) має жити коротко (наприклад, 15 хвилин). Для подовження сесії використовуємо Refresh Token (він живе довше, але зберігається надійніше і його можна відкликати).
2. Де зберігати?
* Новачок: Зберігає в LocalStorage браузера. Це зручно, але вразливо до XSS атак (якщо якийсь скрипт на сторінці вкраде токен).
* Профі: Намагається використовувати HttpOnly Cookies. До них JavaScript не має доступу, а браузер сам відправляє їх на сервер.
3. Не вір клієнту. Навіть якщо токен валідний, завжди перевіряй, чи має цей юзер право на конкретну дію. Те, що у нього є бейдж "Співробітник", не означає, що він може відкрити сейф директора.
6. 🧩 Підсумок
Отже, що ми сьогодні вивчили?
- HTTP — забудькуватий. Йому потрібна допомога, щоб пам'ятати нас.
- JWT — це фестивальний браслет. Він дозволяє серверу зрозуміти, хто ви, не перевіряючи базу даних щоразу.
- Структура: Header + Payload + Signature.
- Головне правило: Підпис гарантує чесність, але не ховає інформацію.
Тепер ви вмієте реалізувати базову авторизацію, яка не "кладе" базу даних зайвими запитами.
🔜 У наступній серії: Гаразд, ми навчилися пускати користувачів за паролем. Але що, якщо ми хочемо, щоб вони заходили через Google або Facebook, не придумуючи нових паролів? Це називається OAuth 2.0. І це... тема нашого наступного уроку!
А поки що — успіхів у кодінгу! 👨💻👩💻