Как я могу использовать базовую HTTP-аутентификацию в PHP?

Я пытаюсь использовать базовую HTTP-аутентификацию и следую примеру на странице руководства PHP . Но у меня это не работает. Кажется, что переменная $_SERVER['PHP_AUTH_USER'] не установлена. Когда пользователь пытается войти в систему, пользователю предлагается новый диалог входа в систему. На сервере работает PHP 5.3.3, и я пробовал использовать Google Chrome и Internet Explorer.

Вот простой пример, который я использовал:

<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
    header('WWW-Authenticate: Basic realm="Jonas Realm"');
    header('HTTP/1.0 401 Unauthorized');
    echo 'User pressed Cancel';
    exit;
} else {
    echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
    echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as you password.</p>";
}
?>

Что не так? Как я могу использовать базовую HTTP-аутентификацию в PHP?


comment
Вместо того, чтобы пытаться сделать это с помощью PHP, почему бы вам не использовать веб-сервер, например http://httpd.apache.org/docs/2.2/howto/auth.html   -  person Phil    schedule 11.11.2010
comment
@James: Я думаю, что мой веб-хостинг использует Apache.   -  person Jonas    schedule 11.11.2010
comment
@Phil: Тогда мой PHP-код не будет зависеть от моего веб-сервера, и я не могу легко перейти на другой веб-сервер. Я хотел бы следовать стандарту HTTP.   -  person Jonas    schedule 11.11.2010
comment
"Неавторизованный" - это в первую очередь орфографическая ошибка. Ваш пример короче ссылки, на которую вы ссылаетесь.   -  person James Black    schedule 11.11.2010
comment
@ Джеймс: Спасибо, но это не помогло.   -  person Jonas    schedule 11.11.2010
comment
@Jonas Честно говоря, использовать htpasswd так просто :)   -  person Phil    schedule 11.11.2010
comment
Вы читали комментарии к ссылке, по которой перешли? Есть предложения для разных веб-серверов и нескольких версий программы, одна из них может лучше подойти для ваших нужд. Для PHP я считаю, что комментарии к руководству более полезны, чем описание в руководстве.   -  person James Black    schedule 11.11.2010


Ответы (5)


Как запускается PHP? Если это через Apache mod_cgi, боюсь, вы вообще не сможете получить информацию для аутентификации. Apache не будет передавать его в приложения CGI, если вы не скомпилируете его с флагом SECURITY_HOLE_PASS_AUTHORIZATION. (То, действительно ли это дыра в безопасности, зависит от того, имеют ли другие пользователи на вашем сервере более низкие или более высокие привилегии, чем пользователи вашего веб-сайта.)

Если это IIS CGI, вы должны убедиться, что настроен только «анонимный» доступ к каталогу, иначе IIS попытается вмешаться и аутентифицировать учетные данные самостоятельно.

echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";

Дыра в безопасности HTML-инъекции (ну если бы работала). Используйте htmlspecialchars(). Чувак, эта страница документации PHP заполнена весьма сомнительными советами и кодом.

Вы также можете попробовать посмотреть на $_SERVER['HTTP_AUTHORIZATION'], хотя я подозреваю, что это проблема с mod_cgi, и в этом случае ни одна переменная не будет присутствовать, и вам придется вместо этого прибегнуть к входу в систему на основе файлов cookie. Или перейдите на хост с более современным подходом к хостингу PHP, например FastCGI или mod_php.

person bobince    schedule 11.11.2010

Попробуй это::

<?php
    /*
    ** Define a couple of functions for
    ** starting and ending an HTML document
    */
    function startPage()
    {
        print("<html>\n");
        print("<head>\n");
        print("<title>Listing 24-1</title>\n");
        print("</head>\n");
        print("<body>\n");
    }

    function endPage()
    {
        print("</body>\n");
        print("</html>\n");
    }
    /*
    ** test for username/password
    */
    if( ( isset($_SERVER['PHP_AUTH_USER'] ) && ( $_SERVER['PHP_AUTH_USER'] == "leon" ) ) AND
      ( isset($_SERVER['PHP_AUTH_PW'] ) && ( $_SERVER['PHP_AUTH_PW'] == "secret" )) )
    {
        startPage();

        print("You have logged in successfully!<br>\n");

        endPage();
    }
    else
    {
        //Send headers to cause a browser to request
        //username and password from user
        header("WWW-Authenticate: " .
            "Basic realm=\"Leon's Protected Area\"");
        header("HTTP/1.0 401 Unauthorized");

        //Show failure text, which browsers usually
        //show only after several failed attempts
        print("This page is protected by HTTP " .
            "Authentication.<br>\nUse <b>leon</b> " .
            "for the username, and <b>secret</b> " .
            "for the password.<br>\n");
    }
?>
person Mazhar Ahmed    schedule 02.01.2011

Для PHP-CGI:

в .htaccess добавьте это:

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
</IfModule>

и в начале вашего скрипта добавьте это:

list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':' , base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
person Teddy    schedule 21.03.2014
comment
Это substr() подозрительно. Я бы сначала разорвал строку на первом пробеле и убедился, что тип аутентификации действительно установлен на Basic (без учета регистра). Затем достаньте вторую часть и расшифруйте ее. - person Alexis Wilke; 22.08.2017
comment
Как я могу реализовать автоматический вход? Я добавил код выше, но я немного не понимаю, с чего начать в моем приложении. - person ; 25.10.2018

Я думаю, что методы PHP полагаются на базовую аутентификацию, настроенную на веб-сервере. Самый простой способ сделать это - включить файл .htaccess в каталог, для которого вы хотите включить базовую аутентификацию.

Большинство веб-хостов на базе UNIX позволяют сделать это, просто загрузив этот файл. В отдельном файле (назовите его .htauth) будут храниться логины пользователей, которым разрешен доступ к сайту или каталогу.

person Ken Richards    schedule 11.11.2010
comment
Это неверно. PHP может полностью контролировать заголовки, отправляемые клиенту (браузеру). - person Phil; 11.11.2010
comment
@phil неправда. Apache всегда отправляет заголовок Server :, и PHP не может этого предотвратить. - person Nicholas Shanks; 24.05.2013

Проверьте, не переопределили ли вы свою переменную $_SERVER[‘PHP_AUTH_USER’] и$_SERVER[‘PHP_AUTH_PW’] перед тем местом, где вы пытаетесь получить доступ к обеим переменным.

Если это не так, проверьте, используете ли вы php как мод cgi или нет. ЕСЛИ вы используете php как мод cgi, то в большинстве случаев вы не получите $_SERVER[‘PHP_AUTH_USER’] и$_SERVER[‘PHP_AUTH_PW’], потому что обычно мы не компилируем apache с опцией SECURITY_HOLE_PASS_AUTHORIZATION. Поэтому, если вы хотите получить обе переменные, перекомпилируйте apache с опцией SECURITY_HOLE_PASS_AUTHORIZATION, или вы можете используйте подход .htaccess.

person Ankur Kumar Singh    schedule 28.01.2017