Руководство по PHP
Пред. |  | След.

# Глава 34. HTTP-Аутентификация в PHP

HTTP-Аутентификация в PHP возможна только в том случае, когда он выполняется как модуль веб-сервера Apache, и, соответственно, недоступна для CGI-версии. Ваш скрипт может использовать функцию header() для того, чтобы отправить браузеру клиента сообщение "Authentication Required", что в свою очередь приведет к появлению диалогового окна для ввода имени пользователя и пароля. После того как клиент ввел свое имя и пароль, скрипт будет вызван повторно, но уже с предопределенными переменными `PHP_AUTH_USER`, `PHP_AUTH_PW` и `AUTH_TYPE`, которые соответственно содержат имя пользователя, пароль и тип аутентификации. Эти переменные могут быть найдены в массиве $_SERVER и `$HTTP_SERVER_VARS`. В настоящее время поддерживается только "Basic"-аутентификация. Также вы можете ознакомится с более детальным описанием функции header().

> Замечание касательно версии PHP: Cуперглобальные переменные, такие как $_SERVER, доступны, начиная с 4.1.0. Массив `$HTTP_SERVER_VARS` доступен в PHP 3 и выше.

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

Пример 34-1. Пример HTTP-аутентификации

`<?php if (!isset($_SERVER['PHP_AUTH_USER'])) { header('WWW-Authenticate: Basic realm="My Realm"'); header('HTTP/1.0 401 Unauthorized'); echo 'Текст, отправляемый в том случае, если пользователь нажал кнопку Cancel'; 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 4.3.0, для того, чтобы предотвратить написание кем-либо скрипта, раскрывающего пароль к странице, которая использует внешнюю аутентификацию, переменные `PHP_AUTH` не устанавливаются в случае, если данная страница использует внешнюю аутентификацию и установлен безопасный режим. Несмотря на это, переменная `REMOTE_USER` может использоваться для аутентификации пользователя, прошедшего внешнюю аутентификацию. Таким образом, вы всегда можете воспользоваться переменной `$_SERVER['REMOTE_USER']`.

> Замечание касательно конфигурации: PHP использует указание директивы `AuthType` для указания того, используется внешняя аутентификация или нет.

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

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

Пример 34-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>Добро пожаловать: {$_SERVER['PHP_AUTH_USER']}<br />";
echo "Предыдущий логин: {$_REQUEST['OldAuth']}";
echo "<form action='{$_SERVER['PHP_SELF']}' METHOD='post'>\n";
echo "<input type='hidden' name='SeenBefore' value='1' />\n";
echo "<input type='hidden' name='OldAuth' value='{$_SERVER['PHP_AUTH_USER']}' />\n";
echo "<input type='submit' value='Авторизоваться повторно' />\n";
echo "</form></p>\n";
}
?>`

Это поведение не регламентируется стандартами HTTP Basic-аутентификации, следовательно, вы не должны зависеть от этого. Как показали тесты, браузер Lynx не очищает кеш авторизации при получении от сервера статуса 401, и, нажав последовательно "Back", а затем "Forward" возможно открыть такую страницу, при условии, что требуемые атрибуты авториазации не изменились. Однако, пользователь может нажать клавишу '_' для очистки кеша аутентификации.

Также следует заметить, что до версии PHP 4.3.3, HTTP-аутентификация не работала на серверах под управлением Microsoft IIS, если PHP был установлен как CGI-модуль, в силу некоторых ограничений IIS. Для того, чтобы добиться корректной работы в PHP 4.3.3+, вы должны отредактировать конфигурационную настройку IIS под названием "Directory Security". Щелкните на надписи "Edit" и установите опцию "Anonymous Access", все остальные поля должны остаться неотмеченными.

Еще одно ограничение, если вы используете IIS посредством ISAPI: переменные `PHP_AUTH_*` не определены, но в то же время доступна переменная `HTTP_AUTHORIZATION`. Пример кода, который вы могли бы использовать: `list($user, $pw) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));`

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

> Замечание: В случае, если используется защищенный режим, UID текущего скрипта будет добавлен в `realm`-часть заголовка `WWW-Authenticate`.

Пред. | Начало | След.
Отличительные особенности | Уровень выше | Cookies