Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
154
Добавлен:
17.02.2016
Размер:
628.22 Кб
Скачать

Лабораторная работа №6 php: механизм сессий

Цель работы: Аутентификация и персонализация пользователей, средствами сервера РНР

Время выполнения: 2 часа

Теоретический материал:

Авторизация с помощью сессий

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

"Сессия" - несколько абстрактное понятие, означающее нечто вроде "законченного периода работы с сайтом ". Например, в сессию могут входить такие действия, как "приход на сайт - загрузка данных - уход с сайта". Иногда определения сессии разнятся в своей формулировке, но суть примерно такая.

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

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

Рисунок 2 - Файлы с данными сессий в папке временных файлов сервера. Имена файлов соответствуют идентификаторам сессий

Рисунок 3 - Содержимое одного из таких файлов. В сессии сохранены переменные: legus, wql, wq2, wq3

Если у посетителя браузер принимает cookie, то ему высылается cookie (с определенным именем - по умолчанию "PHPSESSID"), содержащий так называемый "идентификатор сессии" (рис. 8.9), а если нет, то web-сервер автоматически помещает данный идентификатор в переменную PHPSESSID в каждую ссылку (смотри рисунок) на выдаваемых посетителю страницах сайта (естественно, "внутреннюю" - т. е. ведущую на другие страницы того же самого сайта, с тем же самым доменным именем). Таким образом, идентификатор передается на сервер при каждом заходе посетителя на какую-либо из страниц сайта. При этом идентификатор выбирается либо из соответствующего cookie, установленного посетителю при открытии сессии, либо из адресной строки ссылки, куда этот идентификатор автоматически помещается web-сервером.

Рисунок 4 - Содержимое cookie с идентификатором сессии

Рисунок 5 - Ссылка с идентификатором сессии

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

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

Бесспорно, набор сохраненных переменных, относящихся к одной сессии, будет существовать на сервере не вечно. В параметрах файла конфигурации РНР - php.ini - указывается, какое время жизни устанавливается для cookie с идентификатором сессии (по умолчанию 0 -т. е. до закрытия окна браузера и всех открытых из него окон), а также через какое время данные сессий из папки временных файлов удаляются физически (смотри рисунок). Кроме того, существует специальная команда "разрушения сессии", которая при своем выполнении уничтожает сохраненные в папке временных файлов данные сессии и тем самым делает недействительным идентификатор сессии. Параметры устанавливаемых cookie, в частности, их "время жизни" также можно задать специальной командой в сценарии на РНР, однако время хранения данных сессии в папке временных файлов определяется параметром в php.ini, так что при использовании виртуального хостинга вам не всегда удастся настроить работу с сессиями полностью так, как вам бы хотелось.

Чтобы использовать в сценарии на странице возможности работы с сессиями, необходимо включить в него команду session_start () (так как при работе с сессиями используются cookie, то данная команда должна находиться в начале страницы, перед какими-либо выводимыми в браузер данными) - как при первоначальной установке переменных, так и при последующей работе с ними (если в файле php.ini установлен в 1 параметр session.auto_start, то это делать не обязательно). Чтобы указать, какие переменные следует сохранять в качестве данных сессии, следует использовать команду session register("имя первой переменной", "имя второй переменной",... и т. д.), а чтобы закрыть сессию - команду session_destroy (). При закрытии сессии переменные, переданные сценарию с ее помощью, не обнуляются (последнее делает команда session_unset () ;), так что их можно использовать и в остальной части сценария.

Рисунок 6 - Файл php.ini, раздел настроек параметров сессий

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

Переменные сессии доступны в сценариях сайта по своим изначальным именам. Скажем, если командой session_register переменная $а была зарегистрирована в качестве сессионной, то ее значение будет доступно под тем же самым именем — $а - на всех страницах сайта, где используются сессии (т. е. в их начале размещена команда session_start ()).

Однако в целях безопасности лучше работать в сценарии с переменными сессии через автоматически создаваемые массивы $HTTP_SESSION_VARS и SSESSION, используя одноименные с переменными элементы этих массивов.

Сценарий авторизации

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

Начало сценария на странице проверки логина с паролем может быть таким:

<?php

foreach (file("passw/passwr") as $k)

{if (substr($k, 0, -2)=="$PHP_AUTH_USER $PHP_AUTH_PW")

{$rez=l;}}

if ($rez!=l) {Header("WWW-Authenticate: Basic realm=\"Защищенная зона"\""); Header("HTTP/1.0 401 Unauthorized");

...текст страницы, выдающейся посетителю в случае нажатия им кнопки "Отмена"...

exit,-}

или таким (если логин и пароль передаются из формы в переменных Slogin и Spass):

<?php

foreach (file("passw/passwr") as $k)

{if (substr($k, 0, -2)=="$login $pass")

{$rez=l;

if ($rez!=l) {...текст страницы, выдающейся посетителю в случае ввода неправильных логина и пароля ...

exit;}

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

Продолжение же сценария довольно простое. Создаем сессию...

session_start();

...регистрируем переменную:

session_register("auth");

...и устанавливаем ей определенное значение - дабы потом его и проверять.

$auth=1;

Собственно, и все.

?>

Дальше следует текст страницы, которую посетитель должен увидеть сразу же после успешной авторизации.

На каждой странице "защищенной зоны", в самом ее начале нужно поставить код

<?php session_start();

if ($auth!=l)

{...текст страницы, выдающейся посетителю в случае попытки несанкционированного доступа...

exit;}

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

Страница выхода из "защищенной зоны" должна содержать код (если в файле php.ini установлен в 1 параметр session.autostart, то указывать команду session_start () на каждой странице, где используются переменные сессии или производятся действия с самой сессией, не обязательно).

<?php

session_start(); session_destroy();

?>

После его выполнения для посещения страниц "защищенной зоны" вновь потребуется авторизация.

Пример сценария

Вот пример сценария, в котором используется авторизация на основе заголовка WWW-Authenticate. Он состоит из двух страниц - на первой логин с паролем проверяются и в том случае, если они есть в файле паролей, то посетителю выводится форма для загрузки файла. На второй странице осуществляется загрузка файла.

Файл 1

<?php

foreach (file("passw/passwr") as $k){

if (substr($k, 0, -2)=="$PHP_AUTH_USER $PHP_AUTH_PW")

{$rez=l;} 1

if ($rez!=l) {

Header("WWW-Authenticate: Basic realm=\"Защищенная зона" \" ") ;

Header("HTTP/1.0 401 Unauthorized"); echo ("<р>Доступ закрыт!</р>"); exit;

<FORM ENCTYPE= "multipart/form-data" АСТION ="Файл 2" METHOD=POST>

Закачать файл:<INPUT NAME="zak" TYPE="file"> <INPUT TYPE="submit" VALUE="Закачать">

</FORM>

Файл 2

<?php

foreach (file("passw/passwr") as $k) {

if (substr($k, 0, -2)=="$PHP_AUTH_USER $PHP_AUTH_PW") { $rez=l; }

if ($rez!=l)

{

echo ("<р>Доступ закрыт!</р>");

exit;

if ($zak=="none")

{echo ("Вы забыли указать файл...");} elseif (copy($zak, "папка для файлов/$ zak_name "))

{echo("Файл $zak_name загружен");} else

{ echo("He удалось скопировать $zak_name");} ?>

Соседние файлы в папке Методички ИСИС 230401