Файл: Обеспечение аутентификации и авторизации пользователей в web-приложении.pdf
Добавлен: 03.07.2023
Просмотров: 126
Скачиваний: 4
Для упрощения понимания кода рекомендуется использовать комментарии. Это особенно актуально, если над данным Web-приложением будут работать несколько программистов.[44]
Массив представляет собой особый вид переменных, который содержит несколько значений. Если переменную можно представить в виде ящика, внутри которого находится значение, то массив – это ящик с отделениями, хранящий множество значений в отдельных секциях.
Самый простой способ создать массив в PHP – использовать команду array:
$myArray = array('один', 2, '3');
Приведенный код создает массив $myArray, который содержит три значения: 'один', 2 и'3'. Как и в случае с переменными, значение каждого элемента массива может быть любого типа. В нашем примере первый и третий элементы хранят строки, второй – число.[45]
Чтобы получить доступ к значению, хранящемуся в массиве, нужно знать его индекс. Как правило, для индексации значений внутри массива используются числа начиная с нуля: первое значение (или элемент) массива имеет индекс 0, второе — 1, третье — 2 и т. д, индекс n-го элемента массива равен n– 1. Таким образом, чтобы получить значение нужной вам переменной массива, укажите после ее имени соответствующий индекс в квадратных скобках.
echo $myArray[0]; // выводит 'один'
echo $myArray[1]; // выводит '2'
echo $myArray[2]; // выводит '3'
Каждое значение, хранящееся в массиве, называется элементом массива. Индекс в квадратных скобках используется как для добавления новых элементов, так и для перезаписи уже существующих значений.
$myArray[1] = 'два'; // присваиваем новое значение
$myArray[3] = 'четыре'; // создаем новый элемент
Элементы в конец массива можно добавлять с помощью обычного оператора присваивания. Для этого содержимое скобок, которые следуют за именем переменной, оставляют пустым.[46]
2.2 Работа с механизмом сессий в PHP
Web-сервер не имеет встроенного способа поддержки состояния между двумя транзакциями. Если пользователь запрашивает одну страницу, а затем другию, то с помощью HTTP-протокола, по которому работает Web-сервер, невозможно установить, что оба запроса исходят от одного и того же пользователя.
Вследствие этого, возникла идея управления сеансами, заключающаяся в обеспечении отслеживания пользователя в течение одного сеанса связи с веб-сервером.[47]
Начиная с четвертой версии, в PHP появились собственные встроенные функции управления сеансами. Подход к управлению сеансами несколько изменился с вводом суперглобальных переменных. Теперь можно пользоваться суперглобальным массивом $_SESSION.[48]
Сессии – это процесс, с помощью которого можно создавать и использовать переменные, хранящие свое значение при переходе от одной страницы сайта к другой в течение всего времени посещения пользователем сайта.
Задача опознавания пользователя в течение сеанса (или сессии) работы с сайтом решается путем назначения каждому пользователю уникального номера, так называемого идентификатора сессии (SID, Session IDentifier). Он создаются РНР в тот момент, когда пользователь посещает сайт, и уничтожается, когда пользователь уходит с сайта. Идентификатор сессии характеризует собой строку из 32 символов (например, ac4f4a45bdc897434f95dcaffb1c1811). Этот идентификатор отправляется на сервер вместе с каждым запросом клиента и передается обратно вместе с ответом сервера.
Применяются несколько способов передачи идентификатора сессии:
- С помощью cookies. Cookies были разработаны специально как метод уникальной идентификации клиентов и представляют собой дополнение протокола НТТР. В данном случае идентификатор сессии сохраняется во временном файле на компьютере посетителя, пославшего запрос. Многие пользователи выключают поддержку cookies на своем компьютере из-за проблем с безопасностью.
- С помощью параметров командной строки. В этом случае идентификатор сессии автоматически добавляется во все запросы: (URL), отправляемые серверу, и хранится на стороне сервера.[49]
Например: адрес http://sebastopol.ru/test.php превращается в адрес: sebastopol.ru/test.php?РНРSESSID=a4cf4a45bdc893f5ac95dcaffb1c1811.
По умолчанию в браузер пользователя сессия устанавливает куки с идентификатором автоматически. Затем браузер отправляет это значение вместе с каждым последующим запросом к страницам сайта, чтобы PHP смог определить, к какой именно из текущих сессий (а их может быть несколько) относится данный запрос. Используя набор временных файлов на стороне веб-сервера, PHP отслеживает переменные (и их значения), зарегистрированные в рамках каждой сессии.[50]
На рисунке 5 показано, где сохраняются cookies, когда веб-браузер запрашивает страницы; в данном примере сначала вызывается страница http://example.com/set.php, а затем страница http://example.com/read.php. После посещения первой страницы фактическое значение сохраняется в броузере клиента. Когда клиент запрашивает вторую страницу, вместе с запросом на сервер передается и cookie.[51]
Рисунок 5 – Браузер и сервер взаимодействуют
Чтобы найти идентификатор существующей сессии или создать новую сессию, необходимо вызвать функцию session_start. Отыскав нужный идентификатор, PHP восстановит переменные, которые принадлежат соответствующей сессии. Поскольку данная функция будет пытаться создать куки, ее вызов должен выполняться до того, как браузер получит любые другие данные (аналогично setcookie).
session_start();
Чтобы в рамках сессии создать переменную, используемую на всех страницах сайта для текущего пользователя, добавьте значение в специальный массив $_SESSION. Следующий код сохранит в текущей сессии переменную под названием password.
$_SESSION['password'] = 'mypassword';
Чтобы убрать переменную из текущей сессии, используйте функцию unset.
unset($_SESSION['password']);
И наконец, если вы хотите завершить сессию и удалить все переменные, зарегистрированные в процессе ее существования, вызовите функцию session_destroy и сотрите все сохраненные значения.
$_SESSION = array();
session_destroy();[52]
Команду session_start() нужно добавить во все скрипты, в которых предстоит применение переменные сессии, причем, это нужно сделать, до вывода каких-либо данных в браузер. Это помому, что cookies выставляются только до вывода информации на экран.
Для получения идентификатора текущей сессии применяется функция session_id().[53]
В данной главе был рассмотрен синтаксис языка PHP. Продемонстрировано правильное объявление переменных и массивов. А также показано правильное ведение комментариев в скриптах PHP. И самое главное был рассмотрен механизм сессий, который является основой в раскрытии темы курсовой работы.
3 Обеспечение аутентификации и авторизации пользователей в web-приложении
Для того чтобы пользователь имел возможность представиться системе, необходимо предоставить ему НТМL-форму для входа. Пользователь будет считаться зарегистрированным, если в суперглобальный массив сессии $_SESSION помещены элементы name (имя пользователя) и id_user_password (его пароль).
Процедура авторизации будет осуществляться при помощи функции enter( ) , которая принимает два аргумента: имя пользователя и его пароль и возвращает true В случае успешной авторизации и false - в случае неудачи.
Заметим, что функции, связанные с пользователями, будут размещены в отдельном файле utils.useгs.php, который будет подключаться при помощи директивы require_once.[54]
Приведем пример программы для входа на сайт, функция еnter ():
<?php
function enter ( $name , $password )
// Объявляем название таблицы глобальным
global $tbl_users ;
// Проверяем, соответствует ли логин паролю ,
// и если соответствует - осуществляем авторизацию
$query = "SELECT * FROM $tbl users
WНERE name '$name ' AND
pass = '$password ' AND
?>
block = 'unb1ock '
LIMIT 1";
$usr = mysq1_query ( $query} ;
if( !$usr}
}
throw new ExceptionМySQL (mysq1_error (} ,
$query,
"Ошибка аутентификации" ) ;
$user = mysq1_fetch_array ($usr} ;
// Вход на сайт
$_SESSION [' name ' ] = $user [' name ' ];
$_SESSION ['id_user-роsitiоn' ] = $user ['id_position' ];
// Обновляем дату последнего посещения пользователя
$query = "UPDATE $tbl_users
SET 1astvisit = NOW()
WНERE id_p sition
if ( !mysql_query ($query) )
$user [id_position] ";
throw new ExceptionМySQL (mysq1_error () ,
$query,
"Ошибка аутентификации" ) ;
// Возвращаем признак успешной аутентификации
return true ;
// Возвращаем признак неудачной аутентификации
е1se return false;
Помимо соответствия пароля логину функция проверяет, не является ли запрашиваемый посетитель заблокированным (не принимает ли поле block значение 'block') . Если авторизация пройдена успешно, обновляется значение календарного поля 1astvisit, в котором хранится дата последнего посещения сайта авторизуемым пользователем. [55]
Помимо функции enter() удобно ввести функцию user() , которая принимает единственный параметр - первичный ключ записи в таблице system_users ($tbl_users), а возвращает массив с параметрами пользователя.
Следует обратить внимание, что и в функции user(), и в функции enter( ) переменная $tbl_users, обозначающая имя таблицы, объявлена глобальной (global): это позволяет не передавать имя таблицы в качестве параметра функции. Использование глобальных переменных не рекомендуется, однако в данной ситуации объявление переменной глобальной является оправданным, так как переменные, хранящие имена таблиц, де-факто в приложениях являются глобальными, а префикс $tbl_ исключает искажения значений локальных переменных.[56]
Код программы для получение параметров пользователя, функция user():
<?php
function user($id_position)
// Объявляем имя таблицы $tbl_users глобальным
global $tbl_users;
// Предотвращаем SQL-инъекцию
$id_position = intval($id_position);
// Извлекаем параметры пользователя
$query = "SELECT * FROM $tbl_users
WНERE id_position = $id_position АND
block = 'unblock'
LIMIT 1";
$usr = mysql_query ($query) ;
if(!$usr)
throw new ExceptionМySQL (mysql_error() ,
$query,
"Ошибка извлечения параметров пользователя") ;
if (mysql_num_rows($usr) ) return mysql_fetch_array ($usr) ;
else return 0;
C использованием функций enter() и user () НТМL-форма для авторизации, которая размещается в файле register_enter.php, может выглядеть так, как это представлено ниже. НТМL-форма содержит одно текстовое поле name для имени, поле для пароля раss и флажок remember, установив который пользователь получает возможность не вводить свое имя и пароль в течение недели (сайт «запоминает» его), в противном случае имя и пароль забываются при закрытии браузера. Так как авторизация осуществляется через сессию, сайт «помнит» пользователя только в течение текущего сеанса: уникальный идентификатор сессии (SID) хранится в сессионной cookie, которая, в свою очередь, расположена в оперативной памяти браузера. Для того чтобы сайт «помнил» пользователя между сеансами, необходимо воспользоваться обычными cookie, которые хранятся на жестком диске и устанавливаются при помощи функции setcookie( ).[57]
Код программы для входа на сайт, register_enter.php
<?php
// Инициируем сессию
session_start () ;
// Устанавливаем соединение с базой данных
require_once ("config/config.php" ) ;
// Подкточаем SoftTime FrameWork
require_once ("config/class.config . php " );
// Подключаем функцию вывода текста с bbCode
require_once ("dmn/utils /utils.print_page.php " );
// Подключаем заголовок
require_once ("utils.title.php" );
// Управление пользователями enter(), user()
require_once ( "utils.users.php" ) ;
try
// Если пользователь уже авторизован - инициируем
// элементы НТМL-формы
if (!empty ($_SESSION ['id_user_position' ]))
// Возвращаем данные пользователя с первичным ключом id_user_position
$user = user ( $_SESSION[ ' id_user_position']);
// Инициируем элементы НТМL-формы
$_REQUEST [ ' name ' ]
$user [ ' name ' ] ;
$_REQUEST ['pass ']
$user ['pass '];
// Если данные в cookie не пусты - проверяем их
if (!empty($_COOKIE [' name ' ]) && !empty ( $_COOKIE ['pass ' ]))
(
// Экранируем кавычки для предотвращения
// SQL- инъекции
if (!get_magic_quotes_gpc () )
$_COOKIE [ ' name ' ]
$_COOKIE [ 'pass ']
rnysql_escape_string ( $_COOKIE [' name ']);
rny sql_escape_string ( $_COOKIE ['pass']);
// Осуществляем попытку авторизации с данными ,
// расположенными в cookie
if (enter ( $_COOKIE [' name ' ], $_COOKIE ['pass']))
// Авторизация пройдена успешно - инициируем
// элементы НТМL-формы
$_REQUEST [ ' name ' ]
$_СООКН[' name '];
$_REQUEST ['pass ']
$_COOKIE ['pass']; [58]
// Формируем НТМL- форму
$text = "Поля, отмеченные звездочкой *, являются обязательными к заполнению" ;
$form_cornrnent = new field_paragraph ($text) ;
$ name = new field_text ( " name " ,
"Ник",
true ,
$_REQUEST [' name ']);
new fieldyassword ("pass",
"Пароль " ,
true ,
$_REQUEST ['pass ']);
$remember = new field_checkbox ("remember",
"Запомнить " ,
$_REQUEST ['remember ']);
$form = new form (array ("form_comment " => $form_comment ,
" name "
"pass"
"remember"
"Войти " ,
"main_txt ",
"",
=> $ name,
=> $pass,
=> $remember) ,
"in_input") ;
// Обработчик НТМL-формы
if ( !empty($_POST) ) [59]
{
// Проверяем корректность заполнения НТМL-формы
// и обрабатываем текстовые поля
$error = $form->check() ;
// Проверяем, имеется ли в базе данных пользователь
// с указанным именем
$query
"SELECT COUNT (*) FROM $tbl_users
WНERE пате = '{$form->fields [name] ->value } ''';
$usr = mysql_query ($query ) ;
if( !$usr)
throw new Excepti onМySQL (mysql_error () ,
$query,
"Ошибка извлечения параметров
пользователя" ) ;
if (!mysql_result($usr, 0) )
$error []
"Пользователь с таким именем не существует" ;
if (empty( $error) )
{
// Проверяем, соответствует ли логин паролю
if (enter ($form-> fields ['name ']->value ,
$form->fields ['pass ']->value ))
if ($form->fields ['remember ']->value )
// Если отмечен флажок "Запомнить ", устанавливаем