Применение базовой аутентификации HTTP

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

Решение
Глобальные переменные $_SERVER['PHP_AUTH_USER'] и $_SERVER['PHP_AUTH_PW'] хранят предоставленные пользователем имя и пароль. Для того чтобы закрыть доступ к странице, пошлите заголовок WWW-Authenticate, обозначающий область (realm) аутентификации, вместе с кодом состояния 401:

header('WWW-Authenticate: Basic realm="My Website"');
header('HTTP/1.0 401 Unauthorized');
echo "You need to enter a valid username and password.";
exit;

Обсуждение
Увидев заголовок 401, броузер показывает диалоговое окно для ввода имени пользователя и пароля. Если это удостоверение личности (имя пользователя и пароль) принимается сервером, то оно ассоциируется с областью, указанной в заголовке WWW-Authenticate. Код, который проверяет удостоверение личности (credentials), должен быть выполнен раньше, чем будет послан какой-либо вывод в броузер, т.


к. может быть послан заголовок. Например, это можно сделать с помощью функции, подобной pc_validate(), которая показана в примере 8.2.

Пример 8.2. pc_validate()
function pc_validate($user,$pass) {
/* замените на соответствующую проверку имени пользователя и пароля,
например на проверку в базе данных */
$users = array('david' => 'fadj&32',
'adam' => '8HEj838');
if (isset($users[$user]) && ($users[$user] == $pass)) {
return true;
} else {
return false;
}
}

Ниже приведен пример применения функции pc_validate():
if (! pc_validate($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])) {
header('WWW-Authenticate: Basic realm="My Website"');
header('HTTP/1.0 401 Unauthorized');
echo "You need to enter a valid username and password.";
exit;
}

Замените содержание функции pc_validate() на вашу собственную логику проверки правильности ввода пароля пользователем. Можно также заменить строку области «My Website», а также сообщение «You need to enter a valid username and password», появляющееся при нажатии пользователем кнопки «cancel» в диалоговом окне аутентификации его броузера.

Нельзя применять базовую аутентификацию HTTP, если PHP используется в качестве CGI.


Если нельзя исполнять PHP как серверный модуль, то можно обратиться к аутентификации на основе cookies, рассмотренной в рецепте 8.10.

Другая особенность базовой аутентификации HTTP заключается в том, что она не предоставляет другого способа выхода пользователя из сеанса, кроме закрытия броузера. Руководство по PHP на http://www.php.net/features.http-auth предлагает некоторые способы выхода пользователя, работающие с различной степенью успеха на разных комби-
нациях серверов и броузеров.

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

if (! pc_validate($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW'])) {
$realm = 'My Website for '.date('Y-m-d');
header('WWW-Authenticate: Basic realm="'.$realm.'"');
header('HTTP/1.0 401 Unauthorized');
echo "You need to enter a valid username and password.";
exit;
}

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

Функция pc_validate2() записывает время регистрации в базу данных и вызывает принудительный выход, если прошло более 15 минут с момента последней регистрации пользователя на защищенной странице.

Пример 8.3.


pc_validate2()
Function pc_validate2($user,$pass) {
$safe_user = strtr(addslashes($user),array('_' => '\_', '%' => '\%'));
$r = mysql_query("SELECT password,last_access
FROM users WHERE user LIKE '$safe_user'");
if (mysql_numrows($r) == 1) {
$ob = mysql_fetch_object($r);
if ($ob->password == $pass) {
$now = time();
if (($now - $ob->last_access) > (15 * 60)) {
return false;
} else {
// обновление времени последнего доступа
mysql_query("UPDATE users SET last_access = NOW()
WHERE user LIKE '$safe_user'");
return true;
}
}
} else {
return false;
}
}

Например:
if (! pc_validate($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW'])) {
header('WWW-Authenticate: Basic realm="My Website"');
header('HTTP/1.0 401 Unauthorized');
echo "You need to enter a valid username and password.";
exit;
}

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

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

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