Модуль 24

Сесії та cookies

Ось готовий урок, створений у стилі CS50: енергійний, з аналогіями та акцентом на розумінні суті процесів.


🎓 CS50: Веб-програмування. Тема: Сесії та Cookies

Привіт, друзі! Радий бачити вас знову.

Сьогодні ми поговоримо про те, що робить інтернет "живим". Про те, як Facebook пам’ятає, що це саме ви, коли ви оновлюєте сторінку. Про те, як товари в кошику інтернет-магазину не зникають, коли ви закриваєте вкладку.

Тема нашого уроку: Cookies (Куки) та Сесії.


1. 🔥 Вступ: Проблема «Золотої рибки»

Уявіть, що ви приходите в свою улюблену кав'ярню. Ви підходите до бариста і кажете: "Привіт! Мені як завжди — подвійний лате без цукру". Бариста посміхається, робить каву, ви розраховуєтесь.

Але є нюанс. Уявіть, що у цього бариста — абсолютна амнезія. Його пам'ять стирається кожні 10 секунд.

Ви відходите від каси, робите ковток і розумієте, що забули серветку. Повертаєтесь назад: "Можна мені серветку?". А бариста дивиться на вас порожніми очима і питає: "Вибачте, а ви хто? Ви щось замовляли?".

Звучить абсурдно? Саме так працює протокол HTTP.

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

❓ Риторичне питання: Якби інтернет працював саме так, як би ми могли залогінитися в Instagram? Вам довелося б вводити логін і пароль при кожному натисканні на будь-яку кнопку або фото. Жах, правда?

Нам потрібен механізм, щоб змусити сервер "запам'ятати" нас. І тут на сцену виходять Cookies та Сесії.


2. 🧠 Теоретична база: Клубний браслет

Давайте розберемося, як це працює, не занурюючись у нудні RFC специфікації. Використаємо аналогію Нічного клубу або Спортзалу.

Що таке Cookie (Куки)?

Cookie — це маленький текстовий файл (максимум 4KB), який сервер "дарує" вашому браузеру. Браузер слухняно зберігає його і автоматично показує серверу при кожному наступному запиті.

Аналогія: Ви заходите в клуб. Охоронець (Сервер) перевіряє ваш паспорт (Логін/Пароль) і, якщо все ок, чіпляє вам на руку паперовий браслет. Тепер, коли ви підходите до бару, вам не треба знову показувати паспорт. Ви просто показуєте браслет (Cookie).

Що таке Session (Сесія)?

Сесія — це місце на сервері (у пам'яті або базі даних), де лежить вся інформація про те, що ви зараз робите.

Аналогія: Браслет на вашій руці має лише номер, наприклад, #105. Він не містить вашої куртки, гаманця чи телефону. Але в роздягальні клубу є шафка #105 (Сесія). Саме в шафці лежать ваші речі (дані: ім'я користувача, вміст кошика, налаштування теми).

Як це працює разом ("Під капотом"):

  1. Клієнт (Ви): Вводите логін/пароль.
  2. Сервер: Перевіряє їх. Якщо все ок -> створює "Шафку" (Сесію) у себе в пам'яті. Кладе туди дані: user_id: 42.
  3. Сервер: Генерує унікальний ключ від шафки (Session ID), наприклад, xyz123.
  4. Сервер -> Клієнт: Відправляє відповідь разом із наказом: "Збережи цей Cookie: session_id=xyz123".
  5. Клієнт (наступний запит): Хоче відкрити сторінку профілю. Браузер сам додає до запиту Cookie: session_id=xyz123.
  6. Сервер: Бачить xyz123. Шукає у себе "Шафку" з таким номером. Знаходить user_id: 42.
  7. Сервер: "А, це ж Микола! Ось твій профіль".

⚠️ Що треба запам'ятати залізно:

  • Cookies зберігаються у клієнта (у браузері). Їх можна підробити або вкрасти.
  • Сесії зберігаються на сервері. Це безпечніше.
  • Cookie зазвичай використовується лише як транспорт для передачі ID сесії (ключа від шафки).

3. 🧪 Приклади (Python/Flask стиль)

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

Приклад 1: Просто Cookie (Без сесії)

Ми хочемо запам'ятати, яку мову обрав користувач.

Очікування: Якщо я оберу "UA", то при наступному заході сайт має бути українською.

# Коли користувач натискає "Змінити мову на UA"
resp = make_response("Мову змінено!")
resp.set_cookie('language', 'ukrainian') # Сервер каже браузеру: "Запам'ятай це!"
return resp

# Коли користувач заходить наступного разу
user_lang = request.cookies.get('language') # Сервер питає: "Що там у куках?"
if user_lang == 'ukrainian':
    show_ukrainian_site()

Пояснення: Тут ми зберігаємо дані прямо в Cookie. Це нормально для дрібниць (колір фону, мова), але ніколи не робіть так для важливих даних! Користувач може відкрити налаштування браузера і змінити 'ukrainian' на 'elvis_presley', і ваш код може зламатися.


Приклад 2: Сесія (Реальний логін)

Ми хочемо авторизувати користувача.

Очікування: Після вводу пароля сайт пам'ятає мене, доки я не натисну "Вийти".

# Налаштування (десь у конфігах)
app.secret_key = 'дуже_секретний_ключ' # Потрібен, щоб підписувати cookies

# Логін
def login():
    if password_is_correct():
        # Магія CS50:
        session['user_id'] = 5  # Ми пишемо в "словник", а бібліотека сама створює куку і ховає дані
        return "Ви увійшли!"

# Захищена сторінка
def my_profile():
    if 'user_id' in session: # Перевіряємо, чи є ключ від шафки
        return f"Привіт, юзере номер {session['user_id']}"
    else:
        return "Іди геть, незнайомцю! (Спочатку залогінься)"

Пояснення: Тут ми використовуємо об'єкт session. Для розробника це виглядає як звичайний словник. Але "під капотом" фреймворк створює криптографічно підписаний токен і відправляє його в Cookie. Якщо хакер спробує змінити user_id у куках, підпис не зійдеться, і сервер відхилить запит.


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

Час забруднити руки кодом (або логікою). Уявіть, що ви архітектор системи.

Завдання 1: Лічильник відвідувань Напишіть логіку: коли користувач оновлює сторінку, число на екрані має зростати (1, 2, 3...). Підказка: session['visits'] = session.get('visits', 0) + 1

Завдання 2: "А що, якщо..." (Видалення) Що станеться, якщо користувач вручну видалить Cookie session_id через інструменти розробника (F12 -> Application -> Cookies), а потім оновить сторінку? Відповідь: Сервер не знайде ключа, створить нову порожню сесію, і користувача "викине" з акаунту.

Завдання 3: Кейс "Кошик без реєстрації" Ви помічали, що на Rozetka чи Amazon можна додавати товари в кошик, навіть не залогінившись? Завдання: Опишіть алгоритм, як це реалізувати за допомогою сесій. Рішення: Створюємо тимчасову сесію для "Гостя". Коли (і якщо) він зареєструється — ми просто перенесемо дані з "гостьової" сесії в "постійну".

Завдання 4: Виправ помилку Junior-розробника Джуніор написав код для банку: set_cookie('account_balance', '1000_dollars') Чому цього розробника треба негайно відправити на перенавчання? Що зробить хитрий студент CS50 з цим кукі?


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

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

1. Довіра. Новачок думає: "Я поклав дані в кукі, значить вони там є і вони правильні". Профі думає: "Все, що приходить від клієнта (браузера) — це потенційна брехня, вірус або спроба злому". Ніколи не довіряйте клієнту.

2. Чутливі дані. Новачок зберігає паролі або кредитні картки в Cookies (навіть зашифровані). Профі зберігає в Cookies тільки випадковий ID, який нічого не означає без бази даних сервера.

3. Час життя. Профі завжди думає: "Коли ця сесія має померти?". Якщо ви зайшли в банк з чужого комп'ютера і забули натиснути "Вихід", сесія має сама "згоріти" через 10 хвилин бездіяльності.


6. 🧩 Підсумок

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

  1. HTTP — забудькуватий. Без додаткових інструментів він не пам'ятає вас.
  2. Cookie — це ваша ID-картка. Вона живе у вас у браузері і пред'являється серверу.
  3. Session — це ваша особова справа. Вона лежить на сервері в сейфі. Cookie — це лише номерок від цього сейфу.

Тепер ви вмієте: Розуміти, як сайти "впізнають" вас, і чому не варто зберігати паролі у текстових файлах на комп'ютері клієнта.

🚀 Тизер наступного уроку: Ми сказали, що сесії зберігаються на сервері. Але що, якщо у нас мільйон користувачів? Пам'ять сервера лусне! Нам потрібно десь складати ці дані надійно, структуровано і на віки. Наступного разу ми відкриємо двері у світ Баз Даних та SQL.

А на сьогодні це все. Це був CS50.