HTTP-аутентификация в PHP

Функция header() умеет отправлять в браузер сообщение «Требуется аутентификация» и при этом заставляет браузер показывать всплывающее окно ввода имени пользователя и пароля. Как только пользователь заполнит логин и пароль, браузер снова вызовет URL-адрес с названием PHP-скрипта, но уже с предопределёнными переменными: для переменной PHP_AUTH_USER PHP установит значение имени пользователя, для переменной PHP_AUTH_PW — пароль, а для AUTH_TYPE — тип аутентификации. Эти предопределённые переменные содержит суперглобальный массив $_SERVER. PHP поддерживает только Basic-метод аутентификации. Дополнительную информацию даёт описание функции header().

Пример фрагмента скрипта, который вынуждает клиента авторизоваться для просмотра страницы:

Пример #1 Пример HTTP-аутентификации с типом Basic

<?php

if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="My Realm"');
header('HTTP/1.0 401 Unauthorized');

echo
'Текст, который скрипт отправит,
если пользователь нажмёт кнопку «Отмена»'
;
exit;
} else {
echo
"<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
echo
"<p>Вы ввели пароль: {$_SERVER['PHP_AUTH_PW']}.</p>";
}

?>

Замечание: Примечание о совместимости

При определении HTTP-заголовков соблюдают осторожность. Слово "Basic" требуется писать с заглавной буквы "B", значение для ключа realm берут в двойные, но не одинарные кавычки, а перед кодом 401 в строке заголовка HTTP/1.0 401 указывают ровно один пробел, чтобы гарантировать максимальную совместимость с клиентами. Параметры аутентификации разделяют запятыми.

Вместо простого вывода значений переменных PHP_AUTH_USER и PHP_AUTH_PW, как это сделал приведённый пример, программист может проверить правильность имени пользователи и пароля через базу данных или через поиск пользователя в dbm-файле.

Остерегайтесь браузеров Internet Explorer, которые часто работают с ошибками. Эти браузеры требовательны к порядку заголовков. Трюк с указанием заголовка WWW-Authenticate перед отправкой статуса HTTP/1.0 401, похоже, пока помогает.

Замечание: Примечание о конфигурации

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

Однако обратите внимание, что это не мешает тому, кто контролирует неаутентифицированный URL-адрес, воровать пароли от аутентифицированных URL-адресов на том же сервере.

Браузеры Netscape Navigator и Internet Explorer очистят кеш аутентификации текущего окна для заданного региона (realm) при получении от сервера статуса 401. Это может отменить авторизацию пользователя и заставит его повторно вводить имя пользователя и пароль. Иногда разработчики используют это для ограничения авторизации по времени ожидания или для предоставления кнопки «Выход».

Пример #2 Пример HTTP-аутентификации с принудительным вводом новой пары логин-пароль

<?php

function authenticate()
{
header('WWW-Authenticate: Basic realm="Test Authentication System"');
header('HTTP/1.0 401 Unauthorized');

echo
"Вы должны ввести корректный логин и пароль для получения доступа к ресурсу \n";

exit;
}

if (
!isset(
$_SERVER['PHP_AUTH_USER'])
|| (
$_POST['SeenBefore'] == 1 && $_POST['OldAuth'] == $_SERVER['PHP_AUTH_USER'])
) {
authenticate();
} else {
echo
"<p>Добро пожаловать: " . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "<br />";
echo
"Предыдущий логин: " . htmlspecialchars($_REQUEST['OldAuth']);
echo
"<form action='' method='post'>\n";
echo
"<input type='hidden' name='SeenBefore' value='1' />\n";
echo
"<input type='hidden' name='OldAuth' value=\"" . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "\" />\n";
echo
"<input type='submit' value='Авторизоваться повторно' />\n";
echo
"</form></p>\n";
}

?>

Стандарт базовой аутентификации по протоколу HTTP HTTP Basic не требует такого поведения, поэтому разработчик не должен зависеть от этого. Тестирование браузера Lynx показало, что Lynx не очищает учётные данные аутентификации при ответе сервера кодом 401, поэтому последовательное нажатие кнопок «Назад» и «Вперёд» откроет ресурс, если требования к учётным данным не изменились. Однако пользователь может нажать клавишу '_' для очистки кеша аутентификации.

Чтобы добиться корректной работы HTTP-аутентификации на IIS-сервере с CGI-версией PHP, требуется отредактировать опцию конфигурации IIS-сервера "Directory Security". Щёлкните «Изменить» и поставьте галочку только в поле «Анонимный доступ», остальные поля остаются неотмеченными.

Замечание: Примечание по теме аутентификации на IIS-севере:
Чтобы HTTP-аутентификация корректно работала на IIS-сервере, для PHP-директивы cgi.rfc2616_headers требуется установить значение 0 (значение по умолчанию).