Перейти к содержанию
Innovialabs

Cookies, localStorage или sessionStorage: где хранить данные

Практика3 мин

Коротко

Cookies уходят на сервер с каждым запросом и подходят для сессий с флагами HttpOnly и Secure; localStorage хранит несекретные настройки долго, sessionStorage — до закрытия вкладки.

Короткий ответ

  • Cookies — для данных, которые нужны серверу: прежде всего идентификатор сессии. Защищаются флагами HttpOnly, Secure, SameSite.
  • localStorage — для несекретных данных, которые должны пережить закрытие браузера: тема, язык, черновик формы.
  • sessionStorage — для временного состояния одной вкладки: шаг мастера, фильтры на время сессии.

Секреты — пароли, платёжные данные, долгоживущие токены — в localStorage и sessionStorage не хранятся вообще.

Сравнение

CookieslocalStoragesessionStorage
Срок жизнидо Expires/Max-Age или до конца сессии браузерапока не удалятпока открыта вкладка
Размероколо 4 КБ на одну cookieобычно несколько МБ на originобычно несколько МБ на origin
Отправка на серверавтоматически с каждым запросомнетнет
Доступ из JSда, если нет HttpOnlyдада
Область видимостидомен и путьoriginorigin + конкретная вкладка
APIdocument.cookie, заголовок Set-Cookieсинхронный getItem/setItemсинхронный getItem/setItem

Точные лимиты Web Storage зависят от браузера, поэтому не стоит рассчитывать на них впритык.

Cookies: когда данные нужны серверу

Cookie устанавливает сервер через заголовок или скрипт через document.cookie. Браузер сам прикрепляет её к запросам на подходящий домен.

Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=86400

Что значат флаги:

  • HttpOnly — cookie недоступна из JavaScript. Если на сайт внедрят вредоносный скрипт (XSS), он не сможет её прочитать.
  • Secure — отправляется только по HTTPS.
  • SameSite — ограничивает отправку при запросах с других сайтов и снижает риск CSRF. Lax — разумное значение по умолчанию, Strict — строже, None требует Secure и нужен для сторонних сценариев.
  • Max-Age / Expires — срок жизни. Без них cookie живёт до закрытия браузера.

Минус cookies — они увеличивают каждый запрос. Не храните в них крупные данные.

localStorage: долгие несекретные данные

localStorage.setItem("theme", "dark");
const theme = localStorage.getItem("theme"); // "dark"

Хранит только строки, поэтому объекты сериализуют через JSON.stringify и разбирают через JSON.parse. Данные общие для всех вкладок одного origin, а событие storage позволяет синхронизировать вкладки.

Учтите:

  • API синхронный — большие записи могут подтормаживать интерфейс.
  • В приватном режиме и при запрете хранения доступ может выбросить исключение, поэтому оборачивайте вызовы в try/catch.
  • Любой скрипт на странице, включая сторонний, может прочитать localStorage.

sessionStorage: состояние одной вкладки

Тот же API, но данные живут только в текущей вкладке. Перезагрузка их не стирает, закрытие вкладки — стирает. Две вкладки одного сайта не видят sessionStorage друг друга.

Подходит для многошаговых форм, временных фильтров, позиции в списке.

Что нельзя хранить на клиенте

  • Пароли — ни в каком виде.
  • Данные банковских карт и другие платёжные реквизиты.
  • Долгоживущие токены доступа и refresh-токены в localStorage/sessionStorage: при XSS их украдут. Для сессий надёжнее cookie с HttpOnly.
  • API-ключи с серверными правами — всё, что попало в браузер, пользователь может увидеть.
  • Персональные данные, без которых интерфейс может обойтись.
  • Права и роли как источник истины. Клиент может их подменить, проверка всегда на сервере.

Как выбрать

  1. Нужно серверу при каждом запросе? — cookie.
  2. Секретно? — только HttpOnly-cookie или вообще только сервер.
  3. Должно пережить закрытие браузера? — localStorage.
  4. Нужно только в этой вкладке? — sessionStorage.
  5. Много структурированных данных или файлов? — IndexedDB.

Частые ошибки

  • JWT в localStorage «потому что так в туториале».
  • Cookie без Secure и SameSite на продакшене.
  • Чтение localStorage без try/catch и без значения по умолчанию.
  • Хранение больших объектов в cookies, которые утяжеляют каждый запрос.

Подробности о флагах — в документации MDN.

Частые вопросы

Технически можно, но при XSS-уязвимости токен будет украден. Для сессий безопаснее HttpOnly-cookie с Secure и SameSite плюс защита от CSRF.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.