Учебник РНР
Назад Вперёд

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

HTTP-аутентификация в PHP возможна только при запуске РНР как Apache-модуля и, следовательно, недоступна в CGI-версии. В РНР-скрипте для Apache-модуля можно использовать функцию header() для отправки сообщения "Authentication Required" в клиентский браузер, что вызывает появление в нём окна ввода Username/Password. После того как пользователь ввёл username и password, URL содержащий PHP-скрипт, будет вызван снова с переменными $PHP_AUTH_USER, $PHP_AUTH_PW и $PHP_AUTH_TYPE, в которых установлены имя пользователя, пароль и тип аутентификации, соответственно. В настоящее время поддерживается только аутентификация "Basic". См. также о функции header().

Пример фрагмента скрипта, который форсирует аутентификацию клиента:
Пример 17-1. HTTP Пример аутентификации
<?php
  if (!isset($_SERVER['PHP_AUTH_USER'])) {
    header("WWW-Authenticate: Basic realm=\"My Realm\"");
    header("HTTP/1.0 401 Unauthorized");
    echo "Текст, отправляемый в том случае,
    если пользователь нажал кнопку Cancel\n";
    exit;
  } else {
    echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
    echo "<p>Вы ввели пароль {$_SERVER['$PHP_AUTH_PW']}.</p>";
  }
?>

Примечание: пожалуйста, будьте внимательны при кодировании строк HTTP header'а. Чтобы максимально гарантировать совместимость со всеми клиентами, ключевое слово "Basic" должно быть записано с первой "B" в верхнем регистре, управляющая/realm строка обязана заключаться в двойные кавычки (не одинарные), и точно один пробел должен предшествовать коду "401" в строке "HTTP/1.0 401" header'а.

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

Проследите за работой браузеров Internet Explorer. Они очень чувствительны к порядку header'ов. Отправка WWW-Authenticate header до HTTP/1.0 401 header в данный момент является неким трюком.

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

Замечание о конфигурации: PHP использует наличие директивы AuthType для определения того, действует ли внешняя аутентификация. Исключите эту директиву для контекста, где вам необходимо использовать аутентификацию PHP (иначе каждая попытка аутентификации потерпит неудачу).

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

И Netscape Navigator, и Internet Explorer будут очищать локальный кэш аутентификации окон браузера для сферы/realm при получении ответа 401 сервера. Это может "log out" (выполнить выход) пользователей, форсируя повторное введение ими username и password. Некоторые используют это для "time out" логинов, или предоставляют кнопку "log-out".

Пример 17-2. HTTP аутентификация, форсирующая новые name/password
<?php
  function authenticate() {
    header( "WWW-Authenticate: Basic realm=\"Test Authentication System\"");
    header( "HTTP/1.0 401 Unauthorized");
    echo "Вы обязаны ввести правильные login ID и пароль для доступа к этому ресурсу\n";
    exit;
  }
 
if (!isset($_SERVER['PHP_AUTH_USER'])||($SeenBefore == 1 && $OldAuth == $_SERVER['$PHP_AUTH_USER'])))
  {
   authenticate();
  } 
  else {
   echo "<p>Welcome: {$_SERVER['$PHP_AUTH_USER']}<br>";
   echo "Old: {$_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='Re Authenticate'>\n";
   echo "</form></p>\n";
  }
?>

Это поведение не требуется стандартом HTTP Basic authentication, поэтому вы никогда не должны зависеть от этого. Тестирование для Lynx показало, что Lynx не зачищает показатели аутентификации при ответе 401 сервера, поэтому нажатие back, а затем снова forward, откроет ресурс, если показатель аутентификации не изменились. Пользователь, однако, может нажать клавишу '_' для очистки его информации аутентификации.

Также заметьте, что это не работает на Microsoft IIS-сервере и с CGI-версией PHP из-за ограничений IIS.

Примечание: если safe mode включён, uid скрипта добавляется к части realm шапки WWW-Authenticate.


НазадОглавление Вперёд
Создание изображений и
манипуляции с ними
ВверхКуки