Cookies vs localStorage vs sessionStorage: выбор хранилища
При создании веб-приложения часто требуется хранить данные на стороне клиента — будь то предпочтения пользователя по теме оформления, содержимое корзины покупок или токен аутентификации. Основные три варианта — это cookies, localStorage и sessionStorage. У каждого есть свои особенности, которые делают его подходящим для разных сценариев. Неправильный выбор может привести к уязвимостям безопасности, проблемам с производительностью или плохому пользовательскому опыту.
В этой статье мы разберём различия, дадим практические рекомендации и поможем решить, какой механизм хранения использовать в вашем следующем проекте.
Быстрое сравнение
Прежде чем углубляться в детали, вот общий обзор трёх типов хранилищ:
| Характеристика | Cookies | localStorage | sessionStorage |
|---|---|---|---|
| Ёмкость | ~4 КБ на домен | ~5–10 МБ на origin | ~5–10 МБ на origin |
| Срок хранения | Настраиваемый срок действия | До явной очистки | До закрытия вкладки/окна |
| Отправляется на сервер | Автоматически с каждым HTTP-запросом | Нет | Нет |
| Доступ через JavaScript | Да (если не HttpOnly) | Да | Да |
| Область действия | Домен и путь | Origin (протокол + домен + порт) | Origin + вкладка/окно |
| Уязвимость к XSS | Да (если не HttpOnly) | Да | Да |
| Уязвимость к CSRF | Да (если используется для аутентификации) | Нет | Нет |
Cookies: оригинальное клиентское хранилище
Cookies существуют с первых дней веба. Это небольшие фрагменты данных (максимум ~4 КБ), которые браузер хранит и автоматически отправляет на сервер с каждым HTTP-запросом к тому же домену.
Когда использовать cookies
- Сессии аутентификации: храните идентификаторы сессий или токены, которые сервер должен проверять при каждом запросе. Используйте флаги
HttpOnly,SecureиSameSiteдля снижения рисков XSS и CSRF. - Серверная персонализация: когда сервер должен знать предпочтения пользователя (например, язык, тему оформления) до отрисовки страницы.
- Отслеживание и аналитика: cookies могут сохраняться между сессиями и разделяться между поддоменами при соответствующей настройке.
Вопросы безопасности
Cookies отправляются автоматически, что делает их уязвимыми к CSRF при использовании для аутентификации без дополнительных защит. Всегда устанавливайте атрибут SameSite (Lax или Strict) и рассмотрите использование CSRF-токенов. Для конфиденциальных данных используйте HttpOnly, чтобы запретить доступ через JavaScript и снизить последствия XSS.
Пример установки безопасного cookie в HTTP-ответе:
Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=3600
localStorage: постоянное хранилище «ключ-значение»
localStorage предоставляет простое хранилище «ключ-значение», которое сохраняется даже после закрытия браузера. Данные хранятся в рамках origin (протокол + домен + порт) и не отправляются на сервер автоматически. Идеально подходит для хранения неконфиденциальных данных, которые должны переживать перезагрузку страницы и перезапуск браузера.
Когда использовать localStorage
- Предпочтения пользователя: тема (тёмная/светлая), размер шрифта, язык или настройки макета.
- Кэширование: хранение ответов API или статических данных для сокращения сетевых запросов и улучшения работы офлайн.
- Клиентское состояние: содержимое корзины покупок, черновики форм или флаги функций.
Вопросы безопасности
localStorage доступен через JavaScript, поэтому любая уязвимость XSS может раскрыть все хранящиеся данные. Никогда не храните конфиденциальную информацию, такую как пароли, персональные идентификационные номера или токены аутентификации, если у вас нет надёжной защиты от XSS. Если необходимо хранить токены, рассмотрите подход с использованием cookie HttpOnly.
Пример использования localStorage:
// Сохранить предпочтение пользователя
localStorage.setItem('theme', 'dark');
// Получить предпочтение
const theme = localStorage.getItem('theme');
// Удалить элемент
localStorage.removeItem('theme');
sessionStorage: хранилище для отдельной вкладки
sessionStorage похож на localStorage, но с более коротким сроком жизни: данные очищаются при закрытии вкладки или окна. Он привязан к одной вкладке, поэтому данные не разделяются между вкладками или окнами даже для одного origin.
Когда использовать sessionStorage
- Многошаговые формы: временное хранение данных формы по мере прохождения шагов без сохранения после завершения.
- Состояние отдельной вкладки: данные, которые не должны попадать в другие вкладки, например временное состояние аутентификации или одноразовый токен.
- Конфиденциальные операции: когда вы хотите, чтобы данные автоматически очищались при закрытии вкладки, снижая риск утечки.
Вопросы безопасности
Как и localStorage, sessionStorage уязвим к XSS. Однако ограниченное время жизни и область действия в пределах одной вкладки уменьшают окно возможностей для злоумышленников. Тем не менее избегайте хранения особо конфиденциальных данных.
Пример использования sessionStorage:
// Сохранить данные формы
sessionStorage.setItem('formStep1', JSON.stringify({name: 'John'}));
// Получить данные формы
const step1 = JSON.parse(sessionStorage.getItem('formStep1'));
Как выбрать: руководство по принятию решений
Используйте следующий упорядоченный список для принятия решения:
- Нужно ли серверу читать данные при каждом запросе? Если да, используйте cookies. Пример: идентификаторы сессий.
- Должны ли данные сохраняться между сессиями браузера? Если да, используйте localStorage. Пример: предпочтения пользователя.
- Должны ли данные быть ограничены одной вкладкой? Если да, используйте sessionStorage. Пример: данные многошаговой формы.
- Являются ли данные конфиденциальными? Избегайте хранения в localStorage или sessionStorage. Используйте HttpOnly cookies для токенов и никогда не храните пароли.
- Данные большие? Cookies ограничены ~4 КБ; localStorage и sessionStorage предлагают гораздо большую ёмкость.
Лучшие практики безопасности
- Всегда проверяйте и очищайте входные данные, чтобы предотвратить XSS, который может скомпрометировать любое клиентское хранилище.
- Используйте cookies с HttpOnly, Secure и SameSite для токенов аутентификации, чтобы снизить риски XSS и CSRF.
- Избегайте хранения конфиденциальных данных в localStorage или sessionStorage. Если необходимо, шифруйте их и используйте короткий срок действия.
- Внедрите Content Security Policy (CSP) для снижения рисков XSS.
- Регулярно очищайте устаревшие данные, чтобы не достигать лимитов хранилища и снизить риск утечки.
FAQ
Можно ли использовать localStorage для токенов аутентификации?
Это не рекомендуется, так как localStorage доступен через JavaScript, что делает токены уязвимыми к XSS. Предпочитайте HttpOnly cookies с флагами Secure и SameSite.
Что происходит с sessionStorage при дублировании вкладки?
При дублировании вкладки новая вкладка получает копию sessionStorage исходной вкладки на момент дублирования. После этого они независимы.
Отправляются ли cookies на сервер при каждом запросе?
Да, cookies для текущего домена автоматически включаются в каждый HTTP-запрос, что может влиять на производительность, если хранить слишком много данных. Используйте их умеренно.
Нужно быстро отформатировать или проверить JSON-данные, которые вы сохраняете? Попробуйте наш JSON Formatter, чтобы отформатировать и отладить ваши JSON-полезные нагрузки перед сохранением в клиентское хранилище.