Cookie, localStorage и sessionStorage: разница для тестировщика
Три способа хранить данные в браузере, которые постоянно путают на собеседованиях. Разница практическая: от неё зависит, что произойдёт с сессией пользователя при закрытии вкладки.
Три хранилища в одной таблице
| Cookie | localStorage | sessionStorage | |
|---|---|---|---|
| Уходит на сервер | Да, с каждым запросом | Нет | Нет |
| Время жизни | До указанной даты или до закрытия браузера | Пока не удалят | До закрытия вкладки |
| Объём | Около 4 КБ | Несколько мегабайт | Несколько мегабайт |
| Доступ из другой вкладки | Да | Да | Нет |
| Типичное содержимое | Идентификатор сессии, согласия | Настройки, черновики, кэш | Данные одного сеанса работы |
Ключевая строка — первая. Cookie отправляются на сервер автоматически, поэтому именно в них обычно живёт авторизация. localStorage сервер не видит, пока скрипт сам не положит его содержимое в запрос.
Где это смотреть
DevTools → вкладка Application (в Firefox — Storage). Слева дерево: Cookies, Local Storage, Session Storage, IndexedDB. Значения редактируются прямо там — двойной клик по строке.
Возможность редактировать важнее, чем кажется: это самый быстрый способ проверить, что происходит при испорченных данных. Поменяйте в localStorage сохранённые настройки на мусор и перезагрузите страницу — приложение должно пережить это, а не показать белый экран.
Флаги cookie, о которых спрашивают
- HttpOnly — cookie недоступна скриптам на странице. Обязательна для сессионных: без неё украденный через уязвимость скрипт может прочитать чужую сессию.
- Secure — передаётся только по HTTPS. Без неё сессия уезжает открытым текстом на http-страницах.
- SameSite — ограничивает отправку cookie с чужих сайтов. Защита от подделки запросов; значения Lax, Strict, None.
- Expires / Max-Age — когда истекает. Без них cookie живёт до закрытия браузера.
- Domain и Path — на какие адреса отправляется.
Откройте Application → Cookies и посмотрите на сессионную куку. Если у неё нет HttpOnly или нет Secure на сайте с HTTPS — это дефект безопасности, и заводить его нужно, даже если «так исторически сложилось».
Какие дефекты находят через хранилища
- Выход не выходит. Нажали «Выйти», а cookie осталась. Возврат кнопкой «назад» показывает личные данные.
- Две вкладки живут по-разному. Вышли в одной — вторая продолжает работать, потому что данные в sessionStorage у неё свои.
- Данные прошлого пользователя. Вошли под другим аккаунтом, а в localStorage остались настройки и черновики предыдущего.
- Приложение падает от испорченных данных. Поменяли значение вручную — белый экран вместо понятного поведения.
- Переполнение. В localStorage складывают всё подряд, лимит кончается, и запись падает с ошибкой, которую никто не обработал.
- Чувствительное в открытом виде. Токен, номер карты или персональные данные в localStorage — находка для баг-репорта.
Как проверять сессии по шагам
Универсальный сценарий, который стоит прогнать на любом продукте с авторизацией:
- Войти, посмотреть, что появилось в Cookies и Storage.
- Открыть вторую вкладку — авторизация должна подхватиться.
- Выйти в первой вкладке, перейти во вторую и что-нибудь нажать: должно вернуть на вход, а не показать данные.
- Удалить сессионную cookie руками и обновить страницу — ожидается вход, а не ошибка.
- Дождаться истечения срока (или подставить прошедшую дату) и проверить, что происходит с открытой страницей.
- Проверить, что после выхода в хранилищах не осталось персональных данных.
Дефекты этого класса пропускают чаще всего, потому что позитивный сценарий их не задевает — они живут в переходах между состояниями. Где смотреть сами запросы с cookie, разобрано в статье про вкладку Network.
Кэш браузера — четвёртое место, где прячутся дефекты
Формально кэш не хранилище данных приложения, но проблемы даёт похожие, и путают его с ними постоянно.
Типичная картина: разработчик выкатил правку, у него всё работает, у тестировщика — старая версия. Причина в закэшированных скриптах и стилях. Поэтому в DevTools и включают Disable cache, а перед проверкой правок делают жёсткое обновление (Ctrl+Shift+R).
Что стоит проверять: получает ли пользователь новую версию после выката без ручной очистки кэша; не кэшируются ли ответы с личными данными; не остаются ли в кэше страницы после выхода из аккаунта. Последнее — реальный дефект приватности на общих компьютерах.
IndexedDB — когда данных много
Четвёртое хранилище, о котором вспоминают реже. Это полноценная база в браузере: хранит объёмы больше, умеет индексы и запросы. Используется офлайн-приложениями, чатами, редакторами.
Тестировщику важно знать, что она существует и где лежит (Application → IndexedDB), и проверять там то же самое: остаются ли данные после выхода, что происходит при переполнении, переживает ли приложение очистку хранилища в середине работы.
Что проверять после смены пользователя
Отдельный сценарий, который стоит держать в голове на любом продукте с личным кабинетом: один браузер, два разных аккаунта подряд. Именно здесь всплывают утечки данных между пользователями.
- Вышли из первого аккаунта, вошли во второй — не видно ли остатков: имени, корзины, недавно просмотренного.
- Настройки интерфейса (тема, язык, фильтры) не перетекли от предыдущего пользователя.
- Черновики форм не подставились чужие.
- Кэшированные страницы первого аккаунта недоступны по кнопке «назад».
Что спрашивают на собеседовании?
Разницу между cookie и localStorage (уходит ли на сервер, время жизни) и что такое HttpOnly. Ответ «cookie отправляются с каждым запросом, поэтому там авторизация» закрывает вопрос.
Где хранить токен — в cookie или localStorage?
Единого правильного ответа нет, у обоих подходов свои риски. Тестировщику важнее проверить, что выбранный способ реализован без дыр: флаги у cookie, отсутствие утечки в логи у localStorage.
Как быстро очистить всё для проверки с нуля?
Application → Clear site data, либо режим инкогнито. Инкогнито удобнее: не сбрасывает ваши настройки на других сайтах.