Все разборы

Браузер и DevTools

Как ответить на вопрос «Чем cookie отличаются от localStorage» на собеседовании QA

Cookie, localStorage и sessionStorage: кто отправляет данные на сервер, сколько они живут, что значат HttpOnly, Secure, SameSite и как это проверять в тестах.

Зачем это спрашивают

Все три механизма хранят данные в браузере, и снаружи кажутся одинаковыми. Но у них разный срок жизни, разная область видимости и разное отношение к серверу. Из этих различий вытекают целые классы багов: корзина пропала после перезапуска браузера, пользователь остался залогинен после выхода, во второй вкладке видна старая версия данных.

Интервьюер хочет услышать не определения, а понимание: где лежат данные вашего приложения, кто их читает и что это значит для тест-кейсов. Вопрос про HttpOnly и Secure дополнительно проверяет, знакомы ли вы с базовой безопасностью веба.

Как построить сильный ответ

Начните с главного отличия, затем дайте сравнение по нескольким осям и закончите тем, как это влияет на тестирование.

Главное отличие

Cookie браузер сам прикладывает к каждому HTTP-запросу к своему домену в заголовке Cookie. Сервер устанавливает их заголовком Set-Cookie. localStorage и sessionStorage — хранилища только для JavaScript на странице: на сервер они ничего не отправляют, пока скрипт явно не положит значение в запрос, например в заголовок Authorization.

Сравнение

cookie localStorage sessionStorage
уходит на сервер автоматически с каждым запросом нет нет
срок жизни до Expires / Max-Age; без них — до конца сессии браузера пока не удалят пока открыта вкладка
область домен и путь origin: схема + хост + порт origin и конкретная вкладка
объём около 4 КБ на одну cookie несколько мегабайт на origin несколько мегабайт на origin
доступ из JS да, если нет HttpOnly да да

Важные детали про sessionStorage: данные переживают перезагрузку страницы, но не закрытие вкладки, а две вкладки одного сайта имеют разные хранилища. localStorage, наоборот, общий для всех вкладок одного origin.

Флаги cookie

  • HttpOnly — cookie недоступна через document.cookie, её видит только браузер при отправке запросов. Защищает сессию от кражи через XSS.
  • Secure — cookie отправляется только по HTTPS.
  • SameSite — управляет отправкой при запросах с других сайтов (Strict, Lax, None), защищает от CSRF.
  • Domain и Path — на какие адреса cookie будет отправляться.

Что это меняет для тестов

Знание хранилища подсказывает проверки: перезагрузка, закрытие и открытие браузера, вторая вкладка, режим инкогнито, выход из аккаунта, ручное удаление или порча значения. Всё это делается во вкладке Application в DevTools.

Пример ответа

Главное отличие в том, что cookie браузер сам отправляет на сервер с каждым запросом к домену, а localStorage и sessionStorage доступны только скриптам страницы и на сервер сами не уходят. По сроку жизни: у cookie есть Expires или Max-Age, без них она живёт до конца сессии браузера; localStorage хранится, пока его не очистят; sessionStorage — пока открыта вкладка, и у каждой вкладки он свой. Cookie маленькие, около четырёх килобайт, у хранилищ — мегабайты. HttpOnly запрещает читать cookie из JavaScript, это защита от кражи сессии через XSS. Secure разрешает отправку только по HTTPS. Для тестов это значит, что я проверяю, что происходит после перезагрузки, закрытия браузера, во второй вкладке и после выхода из аккаунта — и смотрю всё это во вкладке Application.

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

  • Сказать, что это «одно и то же хранилище, только разные названия».
  • Думать, что localStorage отправляется на сервер, или что cookie недоступны скриптам всегда, а не только с HttpOnly.
  • Путать sessionStorage с серверной сессией. Это разные вещи: серверная сессия обычно живёт на сервере, а в браузере остаётся только идентификатор в cookie.
  • Считать, что HttpOnly шифрует cookie. Он лишь закрывает доступ из JavaScript, значение по-прежнему видно в DevTools и в запросах.
  • Не связать ответ с тестированием: не назвать ни одной проверки, которую подсказывает тип хранилища.

Пример на MarketCove

В учебном магазине https://shop.tomiddle.com корзина хранится в localStorage, а после входа токен тоже кладётся в localStorage. Представьте, что вам поручили проверить эти два механизма. Набор гипотез получается почти сам собой.

Для корзины:

  • добавьте товар, перезагрузите страницу и закройте браузер — корзина должна сохраниться;
  • откройте магазин в окне инкогнито — корзина там пустая, и это ожидаемо: у приватного окна своё хранилище;
  • найдите в Application ключ, под которым лежит корзина, и посмотрите формат значения — эта деталь пригодится в баг-репорте;
  • сравните со sessionStorage: если бы корзина лежала там, она исчезала бы при закрытии вкладки.

Для входа:

  • выйдите из аккаунта и посмотрите в Application, удалился ли токен;
  • удалите токен вручную и откройте профиль — ожидается предложение войти, а не ошибка;
  • посмотрите в Network, как токен передаётся в запросе к /api/users/me: ожидаемо в заголовке, а не в адресе.

Отдельно полезно понимать, что заказы живут на сервере, а не в браузере: если очистить localStorage и войти снова, история заказов в профиле должна вернуться, пропадёт только корзина. А вот перезапуск сервера сотрёт и заказы, и аккаунты — они хранятся в памяти, и такую ситуацию не стоит путать с багом хранилища.

Задание для практики

Откройте любой сайт, где вы залогинены, и найдите во вкладке Application все три хранилища. Выпишите, какие cookie у них стоят с HttpOnly и Secure, а какие без, и предположите зачем. Затем найдите, где сайт хранит признак входа, и удалите его — что произойдёт при следующем действии? Для сравнения положите тестовое значение в sessionStorage через Console и проверьте, видно ли оно после перезагрузки и в новой вкладке. Закрепить навык помогут квесты по DevTools, а про то, как браузер отправляет cookie в запросе, — статья о том, что происходит после ввода адреса.

Что спросят следом

  • Почему токен авторизации опасно хранить в localStorage?
    Любой скрипт на странице может прочитать localStorage. Если на сайте найдётся XSS-уязвимость, чужой скрипт заберёт токен и отправит его злоумышленнику. Cookie с флагом HttpOnly скрипту недоступна, поэтому этот сценарий для неё закрыт, хотя от других атак она не защищает сама по себе.
  • Что такое SameSite и какие у него значения?
    Атрибут cookie, который определяет, отправлять ли её при запросах, начатых с другого сайта. Strict — только при переходах внутри своего сайта, Lax — ещё и при обычном переходе по ссылке с другого сайта, None — всегда, но только вместе с Secure. Это основная защита от CSRF на уровне браузера.
  • Как проверить поведение приложения, если cookie или токен испорчены?
    Во вкладке Application отредактируйте значение или удалите запись и выполните действие, которое требует авторизации. Ожидаемо приложение должно попросить войти заново и не потерять по возможности введённые данные. Плохие исходы — белый экран, ошибка 500, молчаливый отказ или показ чужих либо устаревших данных.
  1. Q-01
    Что происходит, когда вы вводите адрес сайта в браузере и нажимаете Enter?
  2. Q-02
    Как понять, где баг: на фронтенде или на бэкенде?
  3. Q-03
    Какие коды ответа HTTP вы знаете? Чем 401 отличается от 403?
  4. Q-04
    Что вы проверяете при тестировании API?

Отрепетировать ответ с куратором

В сопровождении — весь банк вопросов, мок-собеседование и разбор каждого настоящего собеседования, пока не придёт оффер. Гарантий трудоустройства не даём — готовим к тому, что спросят.