Аутентификация, основанная на cookies

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

Решение
Сохраните статус аутентификации в cookie или сеансе. В случае успешной регистрации пользователя поместите его имя в cookie. А также поместите хеш из имени пользователя и секретного слова, так чтобы пользователь не смог сконструировать cookie с именем пользователя в нем:

$secret_word = 'if i ate spinach';
if (pc_validate($_REQUEST['username'],$_REQUEST['password'])) {
setcookie('login',
$_REQUEST['username'].','.md5($_REQUEST['username'].$secret_word));
}

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

Username:

Password:



Для проверки имени пользователя и пароля можно применять ту же самую функцию pc_validate() из рецепта 8.9. Единственное различие состоит в том, что в качестве удостоверения личности ей передаются $_REQUEST['username'] и $_REQUEST['password'] вместо $_SERVER['PHP_AUTH_USER'] и $_SERVER['PHP_AUTH_PW'].


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

После того как пользователь прошел авторизацию, сценарий должен лишь удостовериться, что был послан корректный авторизационный cookie, и выполнить некоторые специальные действия для данного зарегистрированного пользователя:

unset($username);
if ($_COOKIE['login']) {
list($c_username,$cookie_hash) = split(',',$_COOKIE['login']);
if (md5($c_username.$secret_word) == $cookie_hash) {$username = $c_username;
} else {
print "You have sent a bad cookie.";
}
}
if ($username) {
print "Welcome, $username.";
} else {
print "Welcome, anonymous user.";
}

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

if (pc_validate($_REQUEST['username'],$_REQUEST['password'])) {
$_SESSION['login'] =
$_REQUEST['username'].','.md5($_REQUEST['username'].$secret_word));
}

Код проверки практически тот же самый, только в нем вместо массива
$_COOKIE используется массив $_SESSION:
unset($username);
if ($_SESSION['login']) {
list($c_username,$cookie_hash) = explode(',',$_SESSION['login']);
if (md5($c_username.$secret_word) == $cookie_hash) {
$username = $c_username;
} else {
print "You have tampered with your session.";
}
}

Применение cookie или сеансовой аутентификации вместо базовой аутентификации HTTP позволяет упростить выход пользователя – достаточно удалить его регистрационный cookie или переменную регистрации из его сеанса.


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

if (pc_validate($_REQUEST['username'],$_REQUEST['password'])) {
$_SESSION['login'] =$_REQUEST['username'].','.md5($_REQUEST['username'].$secret_word));
error_log('Session id '.session_id().' log in as
'.$_REQUEST['username']);
}

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

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


Если Алиса угадает идентификатор сеанса Боба, то она сможет замаскироваться под него на веб-сервере. Модуль сеанса имеет два необязательных параметра конфигурации, затрудняющих угадывание идентификатора сеанса. Параметр session.entropy_file содержит путь к устройству или файлу, которые обеспечивают элемент случайности, например /dev/random или /dev/urandom. Параметр session.entropy_length содержит количество бит, которые надо прочитать из статистического файла при создании идентификатора сеанса.

Не имеет значения, насколько тяжело угадать идентификаторы сеанса, т. к. они могут быть украдены, если пересылаются между сервером и броузером пользователя открытым текстом. Базовая аутентификация HTTP также имеет этот недостаток. Для защиты от просмотра сетевого трафика следует применять SSL.

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела PHP на эту тему:
Буферизация вывода в броузер
Взаимодействие в рамках Apache
Идентификация различных броузеров
Настройка обработки ошибок
Отслеживание сеанса работы с сайтом

Вернуться в раздел: PHP / 8. Основы Web