2.4. Cookie

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

Если сервер будет проверять TCP-соединения и запоминать IP-адреса компьютеров-клиентов, он все равно не сможет различить запросы от двух браузеров, выполняющихся на одной машине. И даже если допустить, что на компьютере работает лишь одна клиент-программа, то никто не может утверждать, что в промежутке между двумя запросами она не была завершена, а затем запущена снова уже другим пользователем.

Тем не менее, если вы когда-нибудь пользовались почтовым ящиком на mail.ru или на другом сервере, предоставляющем почтовые услуги пользователям Веб, вспомните, как вел себя клиент после того, как вы создали для себя почтовый ящик на сервере. Когда вы в следующий раз обратились с того же компьютера к mail.ru, вы, вероятно, заметили, что после загрузки веб-страницы ваше регистрационное имя уже отображалось в соответствующем поле ввода.

Такие сведения позволяет получить дополнительное средство под названием cookie. Механизм cookie позволяет серверу хранить информацию на компьютере клиента и извлекать ее оттуда.

Инициатором записи cookie выступает сервер. Если в ответе сервера присутствует поле заголовка Set-cookie, клиент воспринимает это как команду на запись cookie. В дальнейшем, если клиент обращается к серверу, от которого он ранее принял поле заголовка Set-cookie, помимо прочей информации он передает серверу данные cookie. Для передачи указанной информации серверу используется поле заголовка Cookie.

Для того чтобы в общих чертах представить себе, как происходит обмен данными cookie, рассмотрим следующий пример. Предположим, что клиент передает запросы на серверы А, В и С. Предположим также, что сервер В, в отличие от А и С, передает клиенту команду записать cookie. Последовательность запросов клиента серверу и ответов на них будет выглядеть приблизительно следующим образом.

1.Передача запроса серверу А.

2.Получение ответа от сервера А.

3.Передача запроса серверу В.

4.Получение ответа от сервера В. В состав ответа входит поле заголовка SetCookie. Получив его, клиент записывает cookie на диск.

5.Передача запроса серверу С. Несмотря на то что на диске хранится запись cookie, клиент не предпринимает никаких специальных действий, так как значение cookie было записано по инициативе другого сервера.

6.Получение ответа от сервера С.

7.Передача запроса серверу А. В этом случае клиент также никак не реагирует на тот факт, что на диске хранится cookie.

8.Получение ответа от сервера А.

9.Передача запроса серверу В. Перед тем как сформировать запрос, клиент определяет, что на диске хранится запись cookie, созданная после получения ответа от сервера В. Клиент проверяет, удовлетворяет ли данный запрос некоторым требованиям, и, если проверка дает положительный результат, включает в заголовок запроса поле Cookie.

Таким образом, процедуру записи и получения cookie можно представить себе как своеобразный "запрос" сервера, инкапсулированный в его ответе клиенту. Соответственно, получение cookie также можно представить себе как ответ клиента, инкапсулированный в составе запроса тому же серверу.

Рассмотрим подробнее, какие данные передаются в поле заголовка Set-cookie и как они влияют на поведение клиента.

Поле Set-cookie имеет следующий формат:

Set-cookie: имя = значение; expires = дата; path = путь; domain = имя_домена, secure

где

Пара имя = значение – именованные данные, сохраняемые с помощью механизма cookie. Эти данные должны храниться на клиент-машине и передаваться серверу в составе очередного запроса клиента.

Дата, являющаяся значением параметра expires, определяет время, по истечении которого информация cookie теряет свою актуальность. Если ключевое слово expires отсутствует, данные cookie нe удаляются по окончании текущего сеанса работы браузера.

Значение параметра domain определяет домен, с которым связываются данные cookie. Чтобы узнать, следует ли передавать в составе запроса данные cookie, браузер сравнивает доменное имя сервера, к которому он собирается обратиться, с доменами, которые связаны с записями cookie, хранящимися на клиент-машине. Результат проверки будет считаться положительным, если сервер, которому направляется запрос, принадлежит домену, связанному с cookie. Если соответствие не обнаружено, данные cookie не передаются.

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

Последний параметр, secure, указывает на то, что данные cookie должны передаваться по защищенному каналу.

Для передачи данных cookie серверу используется поле заголовка Cookie. Формат этого поля достаточно простой:

Cookie: имя=значение; имя=значение;  ...

C помощью поля Cookie передается одна или несколько пар имя = значение. Каждая из этих пар принадлежит записи cookie, для которой URL запрашиваемого ресурса соответствуют имени домена и пути, указанным ранее в поле Set-cookie.