Куки обзор

Куки обзор #

Cookie (куки) — небольшие пары «имя=значение», которые браузер прикрепляет к запросам на тот же сайт. Сервер выставляет их заголовком Set-Cookie; JavaScript может читать и записывать часть кук через document.cookie, но с важными ограничениями.


Сервер отвечает, например:

Set-Cookie: sessionId=abc123; Path=/; HttpOnly; Secure; SameSite=Lax

Браузер сохраняет cookie и отправляет её обратно:

Cookie: sessionId=abc123

Так поддерживают сессии входа, корзины на сервере, A/B-тесты и аналитику — в зависимости от настроек.


document.cookie #

В JS куки доступны одной строкой, не как удобный Map:

document.cookie = 'ui_lang=ru; path=/; max-age=31536000'
console.log(document.cookie) // "ui_lang=ru; other=..." — все видимые куки origin

Чтобы прочитать одну куку, строку нужно разобрать:

function readCookie(name) {
  const prefix = `${name}=`
  const pair = document.cookie.split('; ').find((row) => row.startsWith(prefix))
  return pair ? decodeURIComponent(pair.slice(prefix.length)) : null
}

readCookie('ui_lang') // "ru" или null

Запись перезаписывает куку с тем же именем и path; удаление — установка max-age=0 или прошедшей даты expires.

document.cookie = 'ui_lang=; path=/; max-age=0'

Ограничения document.cookie #

ОграничениеСледствие
Только строкаНет getItem/setItem как у localStorage
Нет списка метаданных из JSИз скрипта не видно HttpOnly, Secure, SameSite
Размер ~4 КБ на cookieНе кладите большие JSON
Отправка с каждым запросомЛишний трафик, если cookie раздута
// все куки origin в одной строке — неудобно для сложной логики
document.cookie.split('; ').forEach((row) => console.log(row))

Для клиентских настроек (тема, язык) чаще берут localStorage; куки оставляют там, где сервер должен видеть значение в HTTP-заголовке.


HttpOnly — идея безопасности #

Флаг HttpOnly запрещает доступ к cookie из JavaScript. Такую куку браузер отправит на сервер, но document.cookie её не покажет и скрипт не сможет перезаписать.

// sessionId с HttpOnly — в консоли document.cookie её нет
// XSS-скрипт не украдёт токен через document.cookie

Это основной способ хранить идентификатор сессии: даже при внедрении чужого скрипта на страницу HttpOnly-cookie остаётся недоступной для чтения из JS.

Выставить HttpOnly из браузерного скрипта нельзя — только сервер в Set-Cookie.


Secure, SameSite, Domain #

Кратко о сопутствующих флагах (полностью задаются сервером):

  • Secure — cookie уходит только по HTTPS.
  • SameSite (Strict, Lax, None) — когда cookie прикрепляется к кросс-сайтовым запросам; важно для CSRF и iframe.
  • Domain и Path — на каких URL cookie действует.

Фронтенд должен знать, что сессионная cookie, скорее всего, HttpOnly, и не пытаться дублировать её в localStorage.


Cookies vs Web Storage #

CookieslocalStorage
Отправка на серверАвтоматическиНет
Лимит~4 КБ на cookie~5 МБ на origin
API в JSdocument.cookie (строка)getItem / setItem
HttpOnlyДа (без доступа из JS)Нет такого флага
// клиентская настройка — storage
localStorage.setItem('sidebar-open', '1')

// серверная сессия — Set-Cookie: sid=...; HttpOnly; Secure
// JS проверяет авторизацию через fetch('/api/me'), а не через чтение sid

Итог #

  • Куки связывают браузер и сервер через заголовки Set-Cookie и Cookie.
  • document.cookie — строковый API: неудобен, но достаточен для простых клиентских флагов.
  • HttpOnly скрывает cookie от JavaScript — стандарт для session id.
  • Для UI-настроек удобнее Web Storage; для сессии и CSRF-политики — куки с флагами на бэкенде.

См. также #