Cookie, session, localStorage
HTTP - протокол без состояния. Каждый запрос - как новый звонок от незнакомца. Чтобы сервер помнил пользователя между запросами, нужно хранить состояние. Есть несколько способов - у каждого свои правила (на сервере сессии часто хранят в Redis, на PHP - через сессии).
Cookie
Cookie - маленькие текстовые данные, которые браузер хранит и автоматически отправляет серверу с каждым запросом к этому домену.
// Установка cookie (клиент)
document.cookie = "theme=dark; max-age=2592000; path=/";
// max-age=2592000 - 30 дней в секундах
// Чтение (клиент)
console.log(document.cookie); // "theme=dark; lang=ru"
Сервер устанавливает cookie через заголовок:
Set-Cookie: session_id=abc123; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=86400
Флаги cookie
HttpOnly - JavaScript не может читать (защита от XSS)
Secure - только через HTTPS
SameSite - контроль кросс-доменной отправки:
Strict - не отправлять с других сайтов
Lax - отправлять при навигации (GET), но не POST
None - отправлять всегда (нужен Secure)
Max-Age - время жизни в секундах
Expires - конкретная дата истечения
Path - для какого пути действует cookie
Domain - для какого домена (включая поддомены)
Session (серверная сессия)
Сессия - данные пользователя, которые хранятся на сервере. В cookie хранится только идентификатор сессии (session ID).
Браузер Сервер
│ │
│── Cookie: session_id=abc123 ──→│
│ │── Находит сессию abc123 в памяти/БД
│ │── Сессия: {userId: 42, role: "admin"}
│←── Ответ с данными ───────────│
Преимущества: данные не видны клиенту, нельзя подделать (подделать можно только session ID). Недостатки: нагрузка на сервер, сложнее масштабировать (sticky sessions или shared storage).
localStorage
localStorage - хранилище ключ-значение в браузере. Данные сохраняются бессрочно (пока пользователь не очистит).
// Записать
localStorage.setItem('theme', 'dark');
// Прочитать
const theme = localStorage.getItem('theme'); // "dark"
// Удалить
localStorage.removeItem('theme');
// Очистить всё
localStorage.clear();
Хранение объектов
localStorage хранит только строки. Для объектов - JSON.stringify / JSON.parse:
// Записать объект
const user = { name: 'Иван', role: 'backend' };
localStorage.setItem('user', JSON.stringify(user));
// Прочитать объект
const saved = JSON.parse(localStorage.getItem('user'));
console.log(saved.name); // "Иван"
// Безопасное чтение
function getFromStorage(key) {
try {
const value = localStorage.getItem(key);
return value ? JSON.parse(value) : null;
} catch {
return null;
}
}
sessionStorage
Как localStorage, но данные удаляются при закрытии вкладки.
sessionStorage.setItem('step', '3');
const step = sessionStorage.getItem('step'); // "3"
// Закрыл вкладку → данные пропали
Подходит для: мастер-форм (многошаговых), временных состояний, данных одной сессии.
Сравнение способов хранения
Cookie localStorage sessionStorage
Размер ~4KB ~5-10MB ~5-10MB
Отправка серверу Автоматически Нет Нет
Срок жизни Max-Age/Expires Бессрочно До закрытия вкладки
Доступ из JS Да (без HttpOnly) Да Да
Кросс-вкладки Да Да (один домен) Нет (изолировано)
Что где хранить
✅ Cookie (HttpOnly, Secure):
- Session ID
- Токены аутентификации (если не JWT)
- Настройки, нужные серверу (язык, A/B тест)
✅ localStorage:
- Тема (dark/light)
- Язык интерфейса
- Кешированные данные (прогресс курса)
- Настройки UI (скрытые подсказки)
✅ sessionStorage:
- Данные многошаговых форм
- Временное состояние (позиция скролла)
❌ Никогда не храни в браузере:
- Пароли
- Приватные ключи
- Персональные данные (паспорт, карта)
JWT в localStorage vs HttpOnly cookie
JWT в localStorage:
+ Простой доступ из JS
+ Удобно для SPA
- Уязвим к XSS (скрипт может украсть токен)
JWT в HttpOnly cookie:
+ JS не может прочитать (защита от XSS)
+ Автоматически отправляется серверу
- Нужна защита от CSRF (SameSite помогает)
- Сложнее для кросс-доменных API
Практический пример: тема сайта
// Загрузить тему при старте
const savedTheme = localStorage.getItem('theme') || 'light';
document.documentElement.setAttribute('data-theme', savedTheme);
// Переключить тему
function toggleTheme() {
const current = document.documentElement.getAttribute('data-theme');
const next = current === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', next);
localStorage.setItem('theme', next);
}
[data-theme="dark"] {
--color-bg: #1a202c;
--color-text: #e2e8f0;
}
[data-theme="light"] {
--color-bg: #ffffff;
--color-text: #1a202c;
}
- Python - Аутентификация: JWT, OAuth2 password flow, Depends - как сервер выдаёт и валидирует JWT-токены, хранение refresh-токенов
Мини-задание
- Сохрани тему в localStorage и загружай при открытии страницы
- Посмотри cookies в DevTools → Application → Cookies (найди HttpOnly и Secure)
- Сделай счётчик посещений через localStorage (
visits++) - Сохрани объект в localStorage через
JSON.stringifyи прочитай черезJSON.parse - Сравни: открой два окна с одним сайтом - localStorage общий, sessionStorage раздельный