Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Управление сессиями в PHP, часть 1: Сессии на основе кук

Оригинал: Session Management Using PHP, Part 1: Cookie-based Sessions
Автор: V. Nagaradjane
Дата публикации: 1 Декабря 2008 г.
Перевод: А.Панин
Дата перевода: 4 Марта 2013 г.

Многие из нас используют сессии ежедневно при просмотре веб-страниц. Но интересовались ли вы тем, как сессии реализуются? Наша система электронной почты, журналы, на которые мы подписаны, платные музыкальные каналы, которые мы слушаем - все эти службы используют механизм сессий для идентификации своих пользователей. Механизм управления сессиями позволяет использовать два преимущества: он защищает содержимое веб-страниц от доступа без авторизации и позволяет странице с одной и той же строкой URL вести себя по-разному в зависимости от пожеланий пользователя.

Обычно большинство пользователей не задумываются о том, что происходит при вводе идентификационных данных (имени пользователя и пароля). Вероятно, этот процесс кажется достаточно тривиальным. В одном из моих последних проектов, целью которого была разработка системы для работы с идентификационными данными, мне потребовалось создавать сессии для разграничения прав пользователей. Решение задачи,казавшейся мне ранее очевидной, вызвало значительные затруднения. Я столкнулся с несколькими трудностями при создании надежного механизма сессий и узнал много нового. Позвольте мне поделиться этой информацией с вами в рамках статьи.

Срок реализации проекта был продлен на некоторое время из-за того, что нам хотелось закончить разработку стратегии надежного управления сессиями. В большинстве случаев предоставляемый PHP механизм управления сессиями без вывода каких-либо сообщений об ошибках отказывался работать и мне не удавалось обнаружить причину (позже мне удалось обнаружить, что отключение кук в браузере приводило механизм управления сессиями из PHP в неработоспособное состояние). Можно сказать, что в данной ситуации я выглядел как Чарли Чаплин - выполнение серьезной работы заканчивалось смехотворными результатами. Реализация механизма сессий с использованием базы данных на стороне сервера функционировала корректно, что позволило мне завершить работу над проектом. Неудача при работе с механизмом сессий PHP, в свою очередь, позволила сделать вывод о том, что клиенты, блокирующие куки, не могут использовать сессии.

Что имеется в виду при разговоре о сессиях?

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

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

В двух частях этой статьи (вторая часть будет опубликована позднее) описываются две возможные стратегии создания сессий вместе с их достоинствами и недостатками. При сохранении идентификатора сессии на стороне клиента (об этом мы поговорим в данной статье), он сохраняется в небольшом файле кук. В куках сохраняется имя переменной, ее значение, имя сервера, с которого были переданы данные, время записи данных, период их действия, и.т.д. Данный файл хранится на машине клиента с правами доступа браузера. На механизм хранения кук на машине клиента оказывают влияние настройки браузера.

Хотя стратегия создания сессий с использованием кук и достаточно проста, она имеет несколько слабых мест. Злоумышленники могут проникнуть в систему клиента, найти файл кук и использовать полученную из него пару из ключа и значения для введения сервера в заблуждение, представляясь реальными пользователями. Таким образом, механизм сессий на основе кук не рекомендуется к использованию для проведения финансовых транзакций, так как он не является гарантированно безопасным.

Вторым недостатком механизма создания сессий с использованием кук является тот факт, что консервативные пользователи могут полностью заблокировать установку всех входящих кук. Когда сервер отправляет данные кук для сессии, он предполагает, что клиент сохранит их. Однако, клиент может отклонить эти данные из соображений безопасности и, таким образом, нарушить процесс создания сессии. Это то самое, что происходило в моем проекте. Хотя некоторые попытки открытия сессий были успешны, некоторые сессии не открывались. Причиной такого поведения была блокировка кук, мешающая работе сессий.

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

Требования к проекту

Я буду использовать стек LAMP для реализации механизма управления сессиями. Поэтому перед тем, как преступить к разработке, вы должны проверить доступность необходимых служб на вашей машине. Предполагается, что доступна установленная работающая копия ОС Linux. Несколько слов о серверах Apache и MySQL могут также быть полезны. Проверка состояния серверов Apache и MySQL требует привилегий пользователя root. Используйте либо команду su, либо команду sudo для получения привилегий пользователя root перед вызовом утилиты /sbin/service.

Серверы Apache и MySQL работают в фоновом режиме как демоны и их состояние может быть проверено с помощью команды /sbin/service. При проверке сервер может быть в одном из трех состояний: a) служба доступна и выполняется; b) служба доступна в системе, но не выполняется - осуществить запуск службы достаточно просто; c) служба не доступна в системе - необходимо скачать и установить необходимую службу.

Доступность сервера Apache в системе может быть установлена путем выполнения команды /sbin/service httpd status в окне терминала. Ответом на эту команду может быть строка 'httpd is running', после получения которой мы можем приступить к выполнению следующего шага. Если служба доступна в системе, но не выполняется в данный момент, ответом будет строка 'httpd is stopped'. Никаких проблем! Выполните команду /sbin/service httpd start. Третьим возможным ответом на команду /sbin/service httpd status является строка 'httpd: unrecognized service', говорящая о том, что сервер Apache должен быть установлен на данную машину.

Тестирование доступности служб Apache и MySQL
Рисунок 1: Тестирование доступности служб Apache и MySQL

Повторите описанную выше процедуру для проверки доступности сервера баз данных MySQL в системе, заменив httpd на mysqld в описанной последовательности команд. На Рисунке 1 изображено окно терминала и окно браузера в случае корректной установки служб в системе. Следует отметить, что я использовал установленную версию ОС Fedora 9 при работе над данной статьей. Если команда service не является стандартной командой для запуска и остановки служб (демонов) в вашей системе, пожалуйста, обратитесь к документации для поиска соответствующей команды.

После того, как вы убедитесь в работоспособности служб, проверьте доступность интерпретатора сценариев PHP с помощью команды php -version и обратите внимание на ответ. Если в качестве ответа выводится номер версии, дата сборки и.т.д., значит интерпретатор PHP установлен. Если же в качестве ответа выводится строка "php: command not found", очевидно, вам следует установить PHP.

После того, как серверы Apache и MySQL, а также интерпретатор PHP готовы к работе, вы можете приступать к записку и тестированию сценариев, описанных в данной статье. Читателям, использующим устаревшие версии сервера Apache может потребоваться произвести дополнительную настройку интерпретатора PHP; современные версии сервера не требуют настройки PHP.

Подготовка к работе

Для доступа к содержимому страниц с помощью веб-сервера, данные должны быть помещены в корневую директорию веб-сервера. В случае сервера Apache документы должны быть помещены в директорию /var/www/html/ (или в любую другую директорию, заданную с помощью директивы DocumentRoot в файле /etc/httpd/conf/httpd.conf в вашей системе). Помните о том, что файлы HTML и PHP, описанные в данной статье, находятся в директории, заданной директивой DocumentRoot, /var/www/html/ в моей системе Fedora 9. Размещение любого файла в директории, заданной директивой DocumentRoot сервера Apache разрешает доступ к нему любого клиента, использующего соответствующую строку URL.

Если говорить о базе данных, то она должна содержать как минимум одну таблицу для управления сессиями, в которую должны заноситься имена пользователей и пароли для авторизации с использованием форм входа. Соединитесь с вашим сервером MySQL с помощью следующей команды:
mysql -u <username> -p,
Вам будет предложено ввести пароль MySQL. После ввода пароля, как только вы получите приглашение mysql, вы можете создать базу данных с именем 'session', использовав следующую команду:
create database session; use session;

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

Данной таблицы вполне достаточно для первой статьи, в которой для работы с сессиями используются куки.

Для обработки сессий на стороне сервера с использованием таблицы базы данных (о чем мы поговорим в следующей статье) следует использовать следующую команду после приглашения mysql:

Данная команда создаст таблицу, необходимую для хранения информации о сессиях. На Рисунке 2 показан процесс ввода команд с использованием командной оболочки MySQL.

Создание таблиц базы данных для работы механизма управления сессиями
Рисунок 2: Создание таблиц базы данных для работы механизма управления сессиями

После создания таблиц следует добавить как минимум одного пользователя в таблицу пользователей. Стандартной командой, которую я использовал в тестовых целях, является следующая команда:
insert into user values(0,'admin',encode('good','session'));

Данная команда позволяет добавить пользователя с именем 'admin' и паролем 'good', закодированным с использованием ключа session. Вызов функции decode для пароля потребует того же ключа для получения корректного значения пароля.

Продолжение статьи