Home PageКаталог Изменения НовыеКомментарии Пользователи Регистрация
CakePHP: Manual11/SimpleUserAuth ...

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


Оглавление документа

Общая картина

Если вы новичок в CakePHP, вам настоятельно рекомендуется копировать код и вставлять в свое приложение для использования. Если нет: эта глава — обсуждение ядра Cake, а не безопасности приложений. Я сомневаюсь, что мы будем обсуждать очевидные засады безопасности, главная цель этого примера – показать как работает ядро Cake, и позволить вам создавать пуленепробиваемые приложения.


В Cake есть контроль доступа через встроенный движок ACL, но как насчет аутентификации пользователей?


Что ж, на данный момент мы установили, что система аутентификации пользователей изменяется от приложения к приложению. Некоторые любят хешированные пароли, другие – LDAP (Облегченный протокол доступа к каталогам), и почти все приложения содержат модели User, которые незначительно отличаются. Теперь мы оставляем это на вас. Изменится ли это? Мы не уверены пока. Сейчас, мы думаем, что большие накладные расходы при встраивании этого в фреймворк того не стоят, потому что создание собственной системы аутентификации пользователей с Cake достаточно просто.


Вам нужно всего три вещи:

  1. Способ аутентифицировать пользователей (обычно делается проверкой логина/пароля)
  2. Способ упорно следить что пользователи путешествуют по вашему приложению (обычно делается сессиями)
  3. Способ проверить аутентифицировался ли пользователь (обычно устанавливается с помощью взаимодействия с сессиями)

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


Мы начнем с того, что покажем вам как проверить пользователей, которые пытаются получить доступ к системе. Информация об аутентифицированном пользователе будет храниться в сессии PHP, используя компонент сессий. Когда у нас есть информация пользователя в сессии, мы поместим проверки в приложение, чтобы убедится, что пользователь не пытается добраться до мест, куда ему «не нужно» добираться.


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


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

Аутентификация и стойкость


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

Table 'users', Fictional Client Management System Database

CREATE TABLE `users` (
  `id` int(11NOT NULL auto_increment,
  `username` varchar(255NOT NULL,
  `password` varchar(32NOT NULL,
  `first_name` varchar(255NOT NULL,
  `last_name` varchar(255NOT NULL,
  PRIMARY KEY  (`id`)
)


Достаточно просто, не так ли? Модель Cake для этой таблицы может быть достаточно ясной:

<?php
class User extends AppModel
{
    var 
$name 'User';
}
?>


Первое, что нам нужно это отображение и действие логина. Это даст возможность пользователям логиниться и возможность системе обрабатывать информацию, чтобы узнать давать пользователю доступ или нет. Отображение это простая форма HTML, созданная при помощи HTML Хелпера:

/app/views/users/login.thtml
<?if ($error): ?>
<p>The login credentials you supplied could not be recognized. Please try again.</p>
<? endif; ?>

<form action="<?php echo $html->url('/users/login'); ?>" method="post">
<div>
    <label for="username">Username:</label>
    <?php echo $html->input('User/username', array('size' => 20)); ?>
</div>
<div>
    <label for="password">Password:</label>
    <?php echo $html->password('User/password', array('size' => 20)); ?>
</div>
<div>
    <?php echo $html->submit('Login'); ?>
</div>
</form>


Это отображение предоставляет простую форму логина для пользователей пытающихся получить доступ к системе. Действие для формы это /users/login, находится в Users Controller? и выглядит так:

/app/controllers/users_controller.php (частично)
<?php
class UsersController extends AppController
{
    function 
login()
    {
        
//Не показывать сообщение об ошибке, если данные не были отправлены.
        
$this->set('error'false);

        
//Если пользователь отправил данные из формы:
        
if (!empty($this->data))
        {
            
// Сначала проверим, есть ли пользователи в базе данных
            //с именем, которое предоставил пользователь в форме:

            
$someone $this->User->findByUsername($this->data['User']['username']);

            
// На этом этапе $someone это все данные пользователя, или же она пуста.
            // Давайте сравним пароль из формы с паролем
            //из базы данных.

            
if(!empty($someone['User']['password']) && $someone['User']['password'] == $this->data['User']['password'])
            {
                
// Заметка: надеемся что пароли в вашей БД хешированы,
                // так что ваше сравнение может выглядеть так:
                // md5($this->data['User']['password']) == ...

                // Это значит, что они были одинаковыми. Теперь мы можем создавать некую основную
                //информацию сессии, чтобы запомнить этого пользователя как "залогиненого".

                
$this->Session->write('User'$someone['User']);

                
//Теперь, когда у нас они сохранены в сессии, перенаправим их
                //на нужную страницу в приложении.

                
$this->redirect('/clients');
            }
            
//В другом случае, они предоставили не верные данные:
            
else
            {
                
//Помните переменную $error в отображении? Давайте поставим ее на true:
                
$this->set('error'true);
            }
        }
    }

    function 
logout()
    {
        
//Перенаправляем пользователя на это действие, если они нажали кнопку Выйти.
        //Все что нам здесь нужно, это удалить информацию сессии:

        
$this->Session->delete('User');

        
//Ну и наверняка нам нужно перенаправить их куда-нибудь...
     
        
$this->redirect('/');
    }
}
?>


Не плохо: содержание действия login() может быть меньше 20 линий, если вы были лаконичны. Результат этого действия либо 1: информация пользователя записана в сессию и он перенаправлен на нужную страницу приложения, или 2: отброшен обратно на страницу входа (в дополнении с сообщением об ошибке).

Проверка доступа в вашем приложении


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


Один способ это создать функцию в App Controller?, которая будет делать проверку сессии и отбрасывание.

/app/app_controller.php
<?php
class AppController extends Controller
{
    function 
checkSession()
    {
        
//Если иформация сессии не была установлена...
        
if (!$this->Session->check('User'))
        {
            
//Отправляет пользователя к экрану логина
            
$this->redirect('/users/login');
            exit();
        }
    }
}
?>


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

<?php
class NotesController extends AppController
{
    
// Не хотите, чтобы неаутентифицированный пользователь бродил по каким-либо действия
    // в этом контроллере? Воспользуйтесь beforeFilter, чтобы запускать checkSession
    // перед любым кодом действия.

    
function beforeFilter()
    {
        
$this->checkSession();
    }
}
?>

Принудительная аутентификация перед одним действием контроллера
<?php
class NotesController extends AppController
{
    function 
publicNotes($clientID)
    {
        
//Публичный доступ к этому действию открыт....
    
}

    function 
edit($noteId)
    {
        
// Но вы хотите, что бы этим действием пользовались только аутентифицированные пользователи.
        
$this->checkSession();
    }
}
?>


Теперь вы получили основы, вы можете усовершенствовать возможности аутентификации или настроить их по своему желанию или нуждам. Интеграция с компонентом ACL Cake может быть отличным шагом.


 
Комментарии

Очепятка
доступа к кталогам

v-3990-unlim.vpn.mgn.ru (2008-06-29 11:59:55)

Спасибо за статью!

defi207-842.g.corp.orn.ru (2009-02-04 16:42:50)

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

pool-78-29-51-109.is74.ru (2009-02-09 14:55:47)


ошибаетесь, у каждого пользователя объект $this->Session свой.
62.33.53.244 (2009-03-14 12:44:39)
пам-пам русского автор не знает!

Руки поломать переводчику, пишущему «что бы» раздельно. Вот балван. В 5ом классе это все знают.
host137-218-155-90.butovo.com (2010-08-06 20:05:49)
тут вообще о языках программирования больше, если вы лингвист – вы ошиблись форумом

а вообще камменты на всех страницах жгут
прихожу к выводу, что фрэймворк сей сильно морально устарел, во времена зендов с коханами..
95-79-217-9.pppoe.samara.ertelecom.ru (2010-08-26 17:03:09)
«ошибаетесь, у каждого пользователя объект $this->Session свой.»

а где $this->Session User проверяеться получаеться я могу зайти создав левую куку под именем User
host-94-41-174-22.unknown.o56.ru (2010-11-06 21:41:45)
а где $this->Session User проверяеться получаеться я могу зайти создав левую куку под именем User

Вы ошибаетесь, здесь создается сессия, а не кука! учи мат часть.
dynamicip-109-194-232-97.pppoe.barnaul.ertelecom.r (2011-11-05 14:34:40)
сайт тормозит
31.128.119.37 (2012-07-02 22:18:08)
Добавить комментарий:

Файлы [Скрыть файлы/форму]