В избранное    Домой   

Вторник,  10 Dec 2024 г., 07:25
Порождения ехиднины! как можете говорить доброе, будучи злы? Ибо от избытка сердца говорят уста. /Евангелие от Матфея/

 Логин:  

 Пароль: 




Анонсы:
=== Дата: 24/08/2011     Автор: Крис Ньюман ===

PHP. Урок 15 Аутентификация пользователя

Урок 15. Аутентификация пользователя

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

Типы аутентификации

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

Есть два оптимальных варианта аутентификации пользователя на Web-сайте: с помощью базовой HTTP-аутентификации и с помощью механизма, основанного на сеансах. Ниже рассказывается об отличиях этих методов.

Базовая HTTP-аутентификация

Базовую HTTP-аутентификацию можно реализовать с помощью Web-сервера без участия PHP-сценария. Пример ниже работает для Web-сервера Apache. Для других Web-серверов нужно обратиться к соответствующей документации.

Обычно такая аутентификация устанавливается для каталога, но можно указать и конкретный файл. Файл .htaccess позволяет выполнить специальную настройку папки Web-сайта. Кроме того, в нем можно задать необходимость авторизации перед входом. Обычно набор директив настройки выглядит так:

AuthType Basic
AuthName “Защищенный Web-сайт”
AuthUserFile /home/yourname/htpasswd
require valid-user

AuthUserFile указывает место, где находится файл с паролем, который генерируется утилитой htpasswd. Чтобы создать новый файл с паролем, нужно выполнить следующую инструкцию в командной строке:

$ htpasswd -c /home/yourname/htpasswd chris
New password:
Re-type new password:

Файл паролей. Опция указывается только при создании нового файла. Программа htpasswd не спрашивает о необходимости перезаписать существующий файл. Утилита htpasswd без опции просто добавляет пользователя в существующий файл.

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

chris:XNiv7qSUTFPU6
damon:ZxxE2PTEXeVNU
shelley:SVzAEtxMLEA1s
vanessa:cX/t1Pv2oQfrY

При доступе к файлу в защищенном каталоге в браузере появится окошко с запросом имени пользователя и пароля. Запрошенная страница загрузится только после ввода корректных данных.

Инструкция require valid-user дает указание Web-серверу показывать страницу только авторизированному пользователю. С помощью инструкции require user можно разрешить доступ только для определенных пользователей:

require user chris damon shelley

Базовая HTTP-аутентификация позволяет установить доступ к отдельной части сайта для группы пользователей. С помощью инструкции require group можно разрешить доступ для одной или больше группы пользователей.

Ниже приводится пример файла для групп, который обычно имеет имя htgroups. Он разделяет пользователей в файле паролей на две группы:

boys: chris damon
girls: shelley vanessa

Чтобы разрешить только доступ для группы boys, используется следующий файл .htaccess:

AuthType Basic
AuthName “Только для парней”
AuthUserFile /home/yourname/htpasswd
AuthGroupFile /home/yourname/htgroup
require group boys

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

Дополнительные модули сервера Apache. Некоторые модули сторонних разработчиков для Web-сервера Apache, например mod_auth_mysql и mod_auth_sqlite, позволяют использовать базовую HTTP-аутентификацию в более удобном виде. Вся информация о паролях храниться в базе данных. Но они устанавливаются не на всех Web-серверах.

Аутентификация с помощью сеансов

Полностью управляемый процесс аутентификации пользователя легко реализовать с помощью PHP-сеансов.

Проще говоря, при аутентификации пользователя в сеансе записывается специальная информация. С ее помощью при попытке доступа к защищенным страницам легко идентифицировать пользователя. При авторизации пользователь имя и пароль в соответствующие поля формы. Теперь вид формы и процесс аутентификации можно настроить под конкретные требования.

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

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

Создание системы аутентификации

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

Как работает система

Нужно разработать две компоненты. Одна — отвечает за процесс авторизации. Она проверяет имя пользователя и пароль. Вторая компонента представляет собой блок кода, который нужно добавить в начало всех файлов. Этот блок проверяет переменные сеанса и правильность аутентификации перед тем как, продолжить процесс.

Форма аутентификации. Нужно всегда использовать метод POST для формы аутентификации. Если отправить имя пользователя и пароль с помощью GET, эти значения появятся в URL на следующей странице. И тогда их могут увидеть другие.

Лучше всего выделить блок проверки сеанса в отдельный подключаемый файл auth.inc. Тогда для того, чтобы защитить страницу, достаточно добавить такую инструкцию в сценарий:

include “auth.inc”;

Можно использовать всего одну переменную сеанса для имени авторизированного пользователя. Если переменная содержит имя пользователя, значит, он прошел утентификацию. Тогда для выхода достаточно удалить перемененную сеанса. Это довольно безопасный метод. Потому что конфликтующий сеанс можно создать, только работая на том еже Web-сервере и под тем же именем домена. Тогда файл auth.inc принимает следующий вид:

session_start();
if (!isset($_SESSION[“auth_username”])) {
    echo “Вам нужно пройти аутентификацию, чтобы получить доступ к этой странице”;
    exit;
}

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

Аутентификация пользователя

Ядро формы аутентификации составляют два поля — username и password, а также кнопка подачи формы. Ее можно отформатировать с помощью обычной таблицы. В листинге 15.1 приводится пример простой формы.

Листинг 15.1. Простая форма аутентификации


<FORM ACTION=”login.php” METHOD=”POST”>
<TABLE BORDER=0>
<TR>
    <TD>Имя пользователя:</TD>
    <TD><INPUT TYPE=”TEXT” SIZE=10 NAME=”username”></TD>
</TR>
    <TD>Пароль:</TD>
    <TD><INPUT TYPE=”PASSWORD” SIZE=10 NAME=”password”></TD>
</TR>
</TABLE>
<INPUT TYPE=SUBMIT VALUE=”Авторизироваться”>
</FORM>

Поле пароля. Тип PASSWORD дескриптора <INPUT> работает так же, как и тип TEXT. Но при вводе символы отображаются звездочкам. Для типа PASSWORD есть одно ограничение: нельзя задать стандартное значение с помощью атрибута VALUE.

Сценарий обработки формы login.php ищет полученные значения имени и пароля в списке пользователей. В большинстве случаев достаточно проверить таблицу с пользователями. Сейчас можно создать ассоциативный массив с пользователями, которые имеют доступ к сайту. В листинге 15.2 показано, как это делать.

Листинг 15.2. Сценарий обработки данных аутентификации


<?php
session_start();
$passwords = array(“chris” => “letmein”,
                  “damon” => “thisisme”,
                  “shelley” => “mypassword”,
                  “vanessa” => “opensesame”);

if (!$_POST[“username”] or !$_POST[“password”]) {
    echo “Нужно ввести имя пользователя и пароль”;
    exit;
}
if ($POST[“password”] == $passwords[$_POST[“username”]]) {
    echo “Аутентификация прошла успешно”;
    $_SESSION[“auth_username”] = $_POST[“username”];
}
else {
    echo “Неправильные данные аутентификации”;
}
?>

Сначала создается ассоциативный массив. Ключ соответствует имени пользователя, а пароль значению. Сперва сценарий проверяет наличие значений пароля и имени пользователя.

После этого проверяется значение пароля для ключа с полученным именем пользователя. Если пароли совпадают, пользователь авторизуется. При этом инициализируется переменная сеанса auth_username. В противном случае выводится сообщение об ошибке.

Если проверка в auth.inc прошла успешно, пользователь получит доступ к защищенной странице.

Шифрование паролей

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

Функция PHP crypt предоставляет простой и эффективный алгоритм одностороннего шифрования. Аналогичный механизм использует программа htpasswd и даже система паролей Unix. Чтобы зашифровать пароль, нужно подать его на вход crypt вместе с переменной $salt, которая содержит другую строку, на которой основывается шифрование:

$crypt_password = crypt($password, $salt);

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

Основа. Если при вызове функции crypt опустить строку salt, последняя будет выбрана случайным образом. В результате для двух одинаковых вызовов этой функции на выходе получатся различные результаты. Для строки salt достаточно двух символов. Именно столько используется при шифровке файла паролей Unix в утилите htpasswd.

Процесс кодирования с помощью crypt отличается для различных серверов. Это зависит от библиотек шифрования, которые используются в системе. Поэтому зашифрованные пароли могут несовместимыми между разными системами.

Новая версия login.php приводится в листинге 15.3. Но нужно помнить, что зашифрованные пароли могут не сработать в другой системе.

Листинг 15.3. Сценарий аутентификации с зашифрованными паролями


<?php
session_start();
$passwords = array(“chris” => “ZxsDiRf.VBlWQ”,
                  “damon” => “bQLXBRzdBci7M”,
                  “shelley” => “KkTH39mVsoclc”,
                  “vanessa” => “69SvRIB9QVukk”);
if (!$_POST[“username”] or !$_POST[“password”]) {
    echo “Вам нужно ввести имя пользователя и пароль”;
    exit;
}
$salt = substr($passwords[$_POST[“username”]], 0, 2);
if (crypt($_POST[“password”], $salt) == $passwords[$_POST[“username”]]) {
    echo “Аутентификация успешно пройдена”;
    $_SESSION[“auth_username”] = $_POST[“username”];
}
else {
    echo “Неправильные данные аутентификации”;
}
?>

Строка salt находится в первых двух символах зашифрованной строки. Это позволяет присвоить эти два символа $salt и передать на вход функции crypt. В остальном процесс аутентификации полностью идентичен использованию обычных текстовых паролей.

Анализ удобства использования

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

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

Для того чтобы это реализовать, код в auth.inc должен “знать” адрес и параметры, с которыми пользователь обращался к странице. Эти данные хранятся в переменной $_SERVER[“REQUEST_URI”]. После этого auth.inc выводит форму авторизации вместо того, чтобы выносить ее на отдельную страницу.

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

<INPUT TYPE=”HIDDEN” NAME=”destination”
VALUE=”<?php print $_SERVER[“REQUEST_URI”];?>” >

Вместо сообщения об удачной аутентификации нужно перенаправить пользователя на запрашиваемую страницу с помощью следующего выражения:

header(“Location: $_POST[“destination”]”);

Резюме

В этом уроке вы узнали, как защитить страницу с помощью различных методов аутентификации. В следующем уроке вы увидите, как с помощью PHP получить доступ к другим возможностям HTTP.


<<назад

Погода в Рудне
(Волгоградcкая обл.)

Подробнее >>


Курс валют
на 10 Дек 2024 г.
704 - Вьетнамских донгов
- 1