(C) Зайцев Олег 1998-2002

Программирование на Delphi
обмен опытом

Система | Реестр | Графика | Сети | Мультимедиа | WEB | Разработка_компонент | Железо | Прочее

Cookies - назначение и принципы использования

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

Внимание !! Сайт переехал - он теперь расположен по адресу http://z-oleg.com/delphi, размещенные там материалы переработаны и дополнены. На z-ol.chat.ru остается копия, однако обновляться она больше не будет

Возврат на главную страницу
Статьи, учебные пособия
Гостевая книга - отзывы, вопросы
TopList

Cookies - назначение и принципы использования.

(C) Зайцев О.В., 2002

Мне часть задают вопросы, связанные с разработкой WEB серверов или активных расширений WEB сервера, которые прямо или косвенно затрагивают использование cookies. Поэтому я решил написать эту статью и по возможности наиболее полно осветить все вопросы, связанные с cookies. Кроме того, к статье приложен ряд примеров CGI, демонстрирующих работу с cookies.

Содержание

Назначение cookies

Итак, стоит начать с ответа на вопрос <что такое cookies>. Cookies - это некоторая текстовая информация, которая сохраняется браузером на компьютере пользователя по запросу сервера или по запросу скрипта (или META тега) HTML страницы. Данная информация привязана к имени сервера и (по желанию сервера) к конкретному пути. При последующих обращениях к серверу, оставившему cookie, происходит передача этого cookie в особом поле заголовка HTTP запроса. Очевидно, что для хранения браузер должен вести своего рода базу данных на компьютере пользователя. В IE эта база данных представлена папкой с файлами, имена которых формируются из имени пользователя и имени сервера (например, zaitsev@yandex[2].txt). Кроме того, в этой папке имеется индексный файл index.dat. В Netscape Navigator база данных cookies представлена текстовым файлом с именем cookies.txt, причем одна строка этого файла соответствует одной записи cookie.

У cookies есть несколько типовых применений:

1. Организация сессий. Как известно, стандартный протокол HTTP предполагает работу в транзакциях, т.е. WEB сервер получает HTTP запрос, формирует и передает заголовок ответа, затем передаются данные и после завершения передачи соединение разрывается по инициативе сервера. Таким образом, постоянное соединение между клиентом и сервером отсутствует (в отличие от протоколов FTP, TELNET, SMTP, POP3 и т.п.). Это, с одной стороны, хорошо для WEB сервера. А с другой стороны очень плохо и неудобно - сервер не помнит о предыдущих обращениях пользователей. Конечно, часть проблемы решается и без cookies - можно, к примеру, хранить некоторую информацию с теле WEB страницы - посмотрите, как организована служба Yandex Guru, очень поучительно. Однако применение cookies позволяет имитировать сессию, запоминая в cookies признак успешной идентификации пользователя, его имя, настройки и т.п.

2. Хранение параметров пользователя. Пример - пользователь заполняет сложную форму на 10-20 полей. Через пару дней он опять обращается к данной странице и ему приходится заполнять все снова. Могу привести пример из моей практики: я написал обработчик протоколов прокси-сервера SQUID, который обрабатывает протоколы и помещает статистическую информацию в Oracle. Статистику можно просматривать через WEB интерфейс (написанный к слову сказать на JAVA), заполняя при этом форму параметров, содержащую 10 параметров формирования отчета. Хранение значений, введенных пользователем в форму параметров, в cookies значительно упрощает жизнь пользователю;

3. Осуществление нестандартной идентификации пользователей. После ввода имени и пароля сервер присваивает пользователю некий идентификатор доступа и оставляет на компьютере клиента cookies, хранящий этот идентификатор. При этом особенно интересно использовать cookies без указания времени жизни - они не сохраняются на диске и ассоциированы только с тем окном браузера, которое приняло этот cookies. Я использовал этот нехитрый прием при разработке экзаменатора с WEB интерфейсом;

4. Создание счетчиков, рейтинговых систем и систем голосования с защитой от накрутки (т.е. многократного входа или голосования с одного компьютера). Я бы обманул такую систему в два счета (написав маленькую программу, имитирующую работу браузера), а вот обычному пользователю обмануть такую систему сложнее. Хотя решение есть - найти на диске cookie и стереть его.

Особенности использования cookies

1.Стоит помнить, что cookies хранятся в текстовом виде и могут быть проанализированы или модифицированы пользователем. Следовательно, нельзя использовать cookies при разработке ответственных программ (например, интернет-магазинов) для хранения важной информации;

2.Пользователь может отключить cookies - в браузере есть такая возможность. Следовательно, отключение cookies не должно повлечь за собой потерю работоспособности WEB приложения. Или наоборот, достаточно легко проверить, включена ли поддержка cookies (путем создания одного для пробы) и заблокировать его работу при отключенных cookies;

3.По умолчанию cookies передаются в незашифрованном виде в заголовке HTTP запроса, следовательно, они могут быть перехвачены сниффером. Более того, некоторые прокси-сервера хранят заголовки запросов и ответов (и, следовательно, cookies) в своих протоколах;

4.Браузер не гарантирует хранение cookies в течение заданного срока. Cookies может быть удален в любой момент как по инициативе браузера, так и по желанию пользователя до истечения заданного периода.

Cookies и безопасность пользователя

Мне часто приходится читать в Интернет жуткие истории о том, как при помощи cookies злобные хакеры могут проникнуть на компьютер, выполнить format c: и т.п. На самом деле cookies не представляют особой опасности (HTML страница со скриптами и тегами типа IFRAME или OBJECT куда опаснее!). Cookie - это обыкновенные текстовые строчки, хранимые на компьютере в примитивной базе данных. Каждый браузер имеет ограничения, которые задают максимальный размер cookie (обычно 4 кб), общее количество cookie (обычно 300-500) и максимальное количество cookie, хранимых для одного сервера (обычно около 20). Так что вызвать ситуацию DoS за счет переполнения диска при помощи cookie явно не удастся.

Однако если речь зашла о безопасности, то следует учесть несколько аспектов:

1.Наличие cookies на диске позволяют проанализировать, какие сайты посещал пользователь (точнее, какие из оставляющих cookies сайтов);

2.Анализ cookies иногда позволяет выяснить интересные подробности (например, имя пользователя и пароль к посещенному web ресурсу);


Следовательно, следует сделать ряд выводов:

1.При работе в Интернет с чужого компьютера следует помнить, что посещаемые сайты могут <наследить>, и при необходимости предотвращения подобной ситуации отключать cookies или удалить их по окончанию работы;

2.При разработке своих WEB проектов не следует держать в cookies важную (не говоря уже о конфиденциальной) информацию;

3.Разработчику не следует злоупотреблять размером cookie - лично я никогда не создаю cookie длиннее 1 кб

Следует учитывать, что при уровне безопасности <Средний> в IE Cookies разрешены, при уровне <Высокий> - запрещены. Можно также включить запрос на сохранение cookies, однако эти запросы будут раздражать Вас при работе в Интернет.

Создание cookies

Мне на данный момент известно три способа создания cookies:

1.При помощи передачи параметра Set-Cookie: <определение cookies> в заголовке HTTP ответа. Естественно, этот путь доступен для разработчиков CGI (или иных технологий типа сервлетов или ISAPI) или для разработчиков WEB интерфейса управления, вмонтированного в программу;

2.При помощи META тега в заголовке HTML страницы: <META HTTP-EQUIV="Set-Cookie" CONTENT=" определение cookies">

3.При помощи скрипта. Сделать это просто - у объекта document есть свойство cookie, чтение которого возвращает cookies, а присвоение - сохранение указанного значения. Данный путь особенно интересен для разработчиков, не имеющих возможности размещать на сервере CGI приложения.

Получение cookies

При запросе любого ресурса браузер проверяет, нет ли cookies, которые необходимо передать серверу при запросе документа. Если они есть, то в заголовок HTTP запроса включается параметр Cookie: <значения>. WEB сервер анализирует заголовок запроса и при обнаружении параметра Cookie: он создает переменную окружения HTTP_COOKIE и присваивает ей значение параметра из заголовка запроса. При этом следует учитывать, что WEB сервер совершенно не обязан это делать (он может не уметь работать с Cookie, что часто бывает в простейших WEB серверах, или такая возможность может быть заблокирована).

Я проводил свои опыты с IIS 4.0, IIS 5.0 и Apache Web Server 1.3.12 под операционной системой AIX, эти сервера прекрасно работают с Cookies. Если браузер обнаружит несколько cookie, то их значения будут переданы через точку с запятой, например: MyCookie1=MyVal1; MyCookie2=MyVal2

Формат Set-Cookie

Как я писал выше, для установки значения cookies применяется параметр запроса вида:
 
Set-Cookie: name=<значение>; path=<путь>; expires=<дата>; domain=<домен>; secure 
 
Для создания cookies достаточно только указать первый параметр (т.е. имя и значение), остальные параметры являются необязательными. Рассмотрим подробнее назначение всех элементов строки описание cookies:
Параметр Описание
name=<значение> Определяет имя и значение cookie. В имени и значении недопустимы пробелы, запятые и точка с запятой, символы перевода строки и возврата каретки. Как показали опыты, точка с запятой действительно недопустима, а вот к пробелам и запятым IE относится лояльно. Однако, как показывает моя практика WEB программирования, лучше всего использовать URL-кодирование значения - при этом недопустимые символы исключены, т.к. заменяются кодами. В качестве имени не следует использовать слова PATH, EXPIRES и DOMAIN.
path=<путь> Путь, для которого определен cookie. Этот параметр очень полезен для больших WEB серверов и позволяет связать cookie с конкретными страницами или CGI программами, которые используют этот cookie. По умолчанию path = директории текущего документа. Если задать path=/, то этот cookie будет передаваться при каждом запросе к серверу. Это часто бывает удобно, например, если cookie хранит признак того, что пользователь ввел правильный пароль на доступ к серверу
expires=<дата> Очень важный параметр. Указывает дату, до которой должен хранится данный cookie. Если параметр не указан, то создается cookie особого типа - он не хранится на диске и ассоциирован только с тем окном браузера, которое приняло данные cookie. Этот тип cookie я называю memory cookie (термин естественно неофициальный) и широко использую для примитивной идентификации пользователей, при построении WEB экзаменаторов и т.п. Дата передается в особом формате, пример : Thursday, 14-Feb-2002 18:49:21 GMT. Для упрощения работы с cookie я написал несколько функций, в частности функцию форматирования даты согласно принятому для cookies формату. Эти функции включены в модуль zcookies.pas, который прилагается к примерам.
domain=<домен> Определение домена, для которого действителен данный cookie. Мне на практике не приходилось использовать этот параметр. Если параметр отсутствует, то берется доменное имя текущего сервера.
secure Наличие этого ключевого слова в строке описания cookie сообщает браузеру о том, что данный cookie должен передаваться только через защищенное соединение HTTPS

На заметку:

Примеры программирования с использованием cookies

Как известно, теория без практики мертва. Поэтому рассмотрим ряд примеров. Все примеры основаны на простейшей библиотеках zcookies.pas и zcgi.pas, которые можно скачать с моего сайта. Данные библиотеки упрощают рутинные функции, связанные с cookies - форматирование даты, выполнение URL кодирования/декодирования, выделение cookie по его имени. Если Вы уже скачивали zcgi.pas, то следует загрузить его снова - он был расширен для работы с cookie.

Для опытов примеры необходимо откомпилировать и поместить в папку cgi-bin Вашего WEB сервера.

Пример 1. Простейший пример CGI, который при первом обращении создает два cookie с именем MyCookie1 и MyCookie2. Первый содержит некоторый статический текст, второй - текущую дату и время. Время жизни у данных cookie одинаковое и равно текущей дате + 5 дней. Кроме того, этот пример генерирует страницу, на которой отображается значение cookie, полученное сервером (при первом запросе возвращается пустая строка).

Пример 2. Модификация примера 1, демонстрирующая создание и удаление cookie. При обращении к примеру он выводит форму, позволяющую управлять созданием cookie и их удалением.

Пример 3. Идентификация пользователя при помощи cookie, хранимого в памяти только в течении сеанса работы. Если CGI не получает признак успешного входа в систему, то выводится страница с формой ввода имени пользователя и пароля. Если имя/пароль правильные или установлен признак успешного входа в систему, то возвращается страница с подтверждением успешного входа и кнопкой LogOff, позволяющей выйти из системы. В этом примере используется cookie без параметра expires, поэтому оно хранится только в тем окном браузера, которое получило cookie и только в течении времени его существования. Вы можете открыть второе окно и попробовать обратиться из него к данной CGI - она потребует идентификации.

Пример 4. Счетчик посещений с защитой от <накрутки>. Как и предыдущий пример, он использует cookie без параметра expires, применяемый для защиты от банальной накрутки рейтинга нажатием кнопки <обновить> в браузере. Значение счетчика хранится в INI файле в том же каталоге, что и EXE файл примера.

Исходный текст всех примеров и библиотек можно скачать размещены в одном архиве, который можно скачать здесь.

Использование данных материалов и их размещение на других сайтах возможно только с согласия автора.