Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Cookies Протокол HTTP

HTTP является протоколом без сохранения состояния (англ. stateless protocol). Это означает, что каждая пара запрос-ответ не связана с предыдущим запросом-ответом. В реальной жизни это оказывается не очень удобно, так как иногда нам нужно запомнить аутентификацию пользователя или, например, хранить данные корзины с товаром пользователя в интернет-магазине. Тут возникает проблема: "Как запомнить, что это тот пользователь, с которым мы только что работали?" Решение этой проблемы было найдено более 10 лет назад, когда был придуман механизм, который называется — Cookie.

Механизм работы cookie

Давайте сделаем запрос к сайту Хекслета и посмотрим как этот механизм работает. Мы будем использовать программу curl. Она позволяет делать HTTP запросы и флагами управлять различными их параметрами. В отличие от telnet нам не нужно заранее устанавливать соединение и потом набирать сырой запрос. При работе с curl можно сразу определить параметры и она сама отправит все нужные заголовки запроса, в том числе и по HTTPS.

Давайте выполним запрос для получения только заголовков, для этого добавим к запуску curl флаг --head.

curl --head https://ru.hexlet.io

HTTP/2 200
server: nginx/1.19.1
date: Thu, 16 Jul 2020 03:38:11 GMT
content-type: text/html; charset=utf-8
vary: Accept-Encoding
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
x-download-options: noopen
x-permitted-cross-domain-policies: none
referrer-policy: strict-origin-when-cross-origin
strict-transport-security: max-age=0
x-frame-options: ALLOW-FROM http://webvisor.com
etag: W/"eb99fa0d6ee702b85ba2a5e9b0425aea"
cache-control: max-age=0, private, must-revalidate
content-security-policy:
set-cookie: _hexlet_session2=AiUPd6RFbcrnoGnZSLAYSBzdJqxsQ4sTc%2BW0xXuOKzlenyv5GwkkbpdkD6IVDybDlD8vQcOcgGax98%2FmzIBJrz9f%2BDIJxWRpknZsRSfBXuC9yRfndovBUG6w4fTql4qp7zPozd2veFDLOU4koPVYiUQxgBLM6NkyYg%2Bhs%2BQe%2FSZezleVgMBVD%2FFC070DjV7t2eN01o26kcbd0pQsf9k1LE4JN0aDzSxu8elxLyAWkIJ5l3m%2BcI%2BpgOxk87Uwh9WdTHVuDaraiRaVJz1aZq5hr%2FgzaZiK%2Bgi6ChX60nhha1an610b1v3EE7xgkEM332uFPU0w675fHEr4APTdPDVtJRa3--qQi0cqcljC8i4klD--fXTErw9bhX7%2Fd1xfPE4Gww%3D%3D; domain=.hexlet.io; path=/; expires=Sun, 16 Aug 2020 03:38:11 GMT; secure; HttpOnly; SameSite=Lax
set-cookie: GCLB=CLTE8bzdlaS6Zg; path=/; HttpOnly; expires=Thu, 16-Jul-2020 03:39:50 GMT
x-request-id: 2f554de2-a21d-4e7d-964e-085914ac3f77
x-runtime: 0.056974
access-control-allow-origin: *
via: 1.1 google
alt-svc: clear

Мы видим два заголовка, которые занимаются установкой cookie — set-cookie. Обратите внимание, что каждая cookie посылается в отдельном заголовке. Соответственно таких заголовков может быть достаточно много. Внутри кука представляет из себя пару ключ=значение и отделяется от дополнительных параметров точкой с запятой. Куки сохраняются в браузере на клиенте и при следующем запросе он отправляет их обратно на сервер. Непосредственно в браузере они никак не используются. Хорошая аналогия — это как получить номерок в гардеробе и потом вернуть его, чтобы понять какая куртка ваша. При этом сам номерок никакой ценности не представляет и его нельзя использовать самостоятельно.

Куки делятся как минимум на два типа:

  • Сессионные
  • Постоянные

Сессионные куки в нашем запросе не устанавливаются, так как мы видим дополнительные параметры в заголовке set-cookie. Если бы их не было, то кука называлась бы сессионной. Основное их отличие от постоянных в том, что как только закрывается браузер кука удаляется. Например, на некоторых сайтах, если вы не отметите галочку "запомнить меня" и после закрытия браузера зайдёте на сайт снова, то будете не авторизованы. Так происходит потому, что используется сессионная кука.

Время жизни куки

Время жизни куки

В данном случае устанавливаются постоянные куки. Они сохраняются на жёстком диске и место их хранения может быть разным в зависимости от браузера. Такие куки отличаются от сессионных тем, что можно управлять длиной их жизни при помощи параметра expires.

expires=Thu, 16-Jul-2020 03:39:50 GMT;

В параметре expires указывается дата удаления куки, после которой она не будет отсылаться на сервер. Стоит сказать, что есть еще один параметр, который используется для тех же целей — MAX-AGE. В его значении указывается количество секунд, по истечении которых кука будет удалена.

MAX-AGE=2592000;

Так как часть браузеров не поддерживают MAX-AGE, некоторые фреймворки часто устанавливают сразу оба параметра и браузеры просто игнорируют тот, который им не нужен. Таким образом заголовок set-cookie, который содержит два параметра MAX-AGE и expires, считается валидным. В стандарте также говорится и о том, что регистр имени куки не имеет значения.

Параметры domain и path

Параметры domain и path задают область видимости куки, то есть URL, на которые кука может отправляться. Если они не заданы, то по умолчанию кука будет пересылаться на сервер только для текущего пути и домена. В нашем примере в path указан корень сайта.

domain=.hexlet.io; path=/;

То есть кука будет отправляться для всех страниц. Есть нюанс, если установлен domain=.hexlet.io, причём наличие точки перед именем домена не имеет значения, то кука будет работать не только для всех страниц сайта, но и для всех поддоменов. А если мы совсем не установим параметр domain, хотя по умолчанию его значение будет hexlet.io, то кука для поддоменов работать не будет.

Уникальность куки определяется тремя параметрами key (имя куки), domain и path. Это значит, что если какую-то куку нужно переустановить, например, поменять время её жизни, то при следующем запросе в set-cookie эти параметры должны совпадать. Если хотя бы один из них отличается, то будет установлена новая кука.

Удаление куки

Заголовка для удаления куки не существует, чтобы удалить её, нужно установить нулевой или отрицательный MAX-AGE, либо задать expires в прошлом, тогда кука будет немедленно удалена.

Можно заметить, что в нашем примере установлен дополнительный параметр HttpOnly. HttpOnly куки передаются с AJAX-запросами, но их нельзя получить через JavaScript на странице сайта. Это дополнительный уровень безопасности от XSS атак.

Отправка на сервер

После того как мы обновляем страницу в браузере, происходит отправка следующего заголовка:

cookie: GCLB=CLiC7uWajOOrzAE; _hexlet_session2=gu3n8MCidqZ28VfjpzJuF74d4ohla6uYq9Q%2B2XBcalsa3VUCzURBWTXvscuzSI%2BF3lnHAN%2FUt6IJnXgkH%2B6jDKgyStVb8W%2BLHwIbypoxajN3fB5ksFT3Qu28RvDQpL6hBmqq7V2eFdfLMGtkmtcpfAUYNGffwaBAlQyQKnvhkCpEf5IIWkwWfe9Nt8dG3lIueeir9fGxZP7Fpcw9IP9HfgSansgXugtFI1rw06UhgrrK%2BEnaf4EmIgVdH6KYpDBKXpUUXz8vFRvkOMX5j%2BZNMTu%2BKDBzmGlFjcm1mCZl4ozZWDCocFO4CTW7z9LmzKYbcEGkUEhRbOu%2BTvLgVo80LilK--x3y6jxx%2FjYcLp5tr--9nrQ0XmAhtGAuIFvMYvWig%3D%3D

Все куки отправляются одним заголовком в формате key=value; key=value без дополнительных параметров.


Дополнительные материалы

  1. HTTP Cookie / Mozilla
  2. HTTP Куки / Википедия
  3. RFC 6265: стандарт, описывающий cookie

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Фронтенд-разработчик
Профессия
Разработка фронтенд-компонентов веб-приложений
30 июня 10 месяцев
Иконка программы Python-разработчик
Профессия
Разработка веб-приложений на Django
30 июня 10 месяцев
Иконка программы PHP-разработчик
Профессия
Разработка веб-приложений на Laravel
30 июня 10 месяцев
Иконка программы Node.js-разработчик
Профессия
Разработка бэкенд-компонентов веб-приложений
30 июня 10 месяцев
Иконка программы Fullstack-разработчик
Профессия
Новый
Разработка фронтенд и бэкенд компонентов веб-приложений
30 июня 16 месяцев
Иконка программы Java-разработчик
Профессия
Разработка приложений на языке Java
30 июня 10 месяцев

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»