Зарегистрируйтесь, чтобы продолжить обучение

Cookies Протокол HTTP

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

Изначально работать с HTTP было не очень просто. Дело в том, что это протокол без сохранения состояния, то есть каждый запрос-ответ не связан с предыдущим запросом-ответом. Это было неудобно, потому что иногда нам приходится запоминать информацию: например об аутентификации пользователя или о товарах в его корзине в интернет-магазине.

Тут возникает проблема: «Как запомнить, что это тот пользователь, с которым мы только что работали?». Решение этой проблемы было найдено когда был придуман механизм, который называется Cookie.

В этом уроке мы разберемся, что такое куки и как они работают.

Как работают куки

Давайте сделаем запрос к сервису HTTP Server и посмотрим, как этот механизм работает

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

curl --head https://http.hexlet.app/http-protocol/example

HTTP/2 200
date: Wed, 02 Oct 2024 15:05:59 GMT
content-type: text/html; charset=ISO-8859-1
accept-ranges: none
cache-control: private, max-age=0
expires: -1
p3p: CP="This is not a P3P policy! See g.co/p3phelp for more info."
set-cookie: 1P_JAR=2020-01-18-09; expires=Mon, 17-Feb-2020 09:24:50 GMT; path=/; domain=.hexlet.app; Secure
set-cookie: NID=196=wsHLMAMfnAaSyF7zduokI8TJeE5UoIKPHYC58HYH93VMnev9Nc2bAjhRdzoc4UhmuOd7ZVCorDnzGDe51yPefsRMeVyOFnYdHYYgQNqI8A1dYuk4pDK4OJurQgL4lX8kiNGSNi_kkUESFQ-MqLCB_YspxA9JRejhZdkTRtGyHNk; expires=Sun, 19-Jul-2020 09:24:50 GMT; path=/; domain=.hexlet.app; HttpOnly
vary: Accept-Encoding
x-frame-options: SAMEORIGIN
x-xss-protection: 0
cf-cache-status: DYNAMIC
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=9ileixnwWqNV5AorloHI%2FKLp9Kw17SfIpzJK9XGAj2QNpomfZ4iNA0qmZojD7NuKahGwh43YcZ83hgmFRRCcQ9tubJWyGvtw14R4WKJRDWcMIqzn8meMSbRYAI6S0q2UXv0%3D"}],"group":"cf-nel","max_age":604800}
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
speculation-rules: "/cdn-cgi/speculation"
server: cloudflare
cf-ray: 8cc597ff1f6c0ebd-HKG

Мы видим два заголовка, которые занимаются установкой 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.app; path=/;

Обратите внимание на одну важную деталь в этом примере. Если установлен domain=.hexlet.app, то кука будет работать не только для всех страниц сайта, но и для всех поддоменов — при этом наличие точки перед именем домена не имеет значения. Если мы совсем не установим параметр domain, то кука для поддоменов работать не будет, хотя по умолчанию значение домена будет hexlet.app.

Уникальность куки определяется тремя параметрами 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
  4. Local Storage vs. Session Storage vs. Cookie

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

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

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

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

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

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

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

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

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

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

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
Верстка на HTML5 и CSS3, Программирование на JavaScript в браузере, разработка клиентских приложений используя React
10 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на Python, Разработка веб-приложений и сервисов используя Django, проектирование и реализация REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
Тестирование веб-приложений, чек-листы и тест-кейсы, этапы тестирования, DevTools, Postman, SQL, Git, HTTP/HTTPS, API
4 месяца
с нуля
Старт 26 декабря
профессия
Программирование на Java, Разработка веб-приложений и микросервисов используя Spring Boot, проектирование REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на PHP, Разработка веб-приложений и сервисов используя Laravel, проектирование и реализация REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на JavaScript в браузере и на сервере (Node.js), разработка бекендов на Fastify и фронтенда на React
16 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на JavaScript, разработка веб-приложений, bff и сервисов используя Fastify, проектирование REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
новый
Git, JavaScript, Playwright, бэкенд-тесты, юнит-тесты, API-тесты, UI-тесты, Github Actions, HTTP/HTTPS, API, Docker, SQL
8 месяцев
c опытом
Старт 26 декабря

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

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

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

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»