Home PageКаталог Изменения НовыеКомментарии Пользователи Регистрация
CakePHP: Manual11/BlogTutorial ...
Это старая версия Manual11/BlogTutorial за 2007-10-23 22:49:24..

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


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

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

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


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


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


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

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

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


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


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


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

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


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


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 может быть отличным шагом.


 
Комментарии

ниче не понятнооо......

ns.elecard.net.ru (2008-12-25 09:45:37)

супер!
жаль что про cake я не слышал пару лет назад...
щас не пришлось бы поддерживать столько беспорядочного кода =)

95.78.67.103 (2009-01-06 14:18:02)

Полезным будет добавление к даному примеру использование страничной навигации.

pool-78-29-43-128.is74.ru (2009-02-09 13:43:05)
очень хорошая статья для понимая основ Cake PHP?
79-128-113-92.pool.ukrtel.net (2009-04-14 20:06:52)
Супер, спасибо.
bestcom.static.khakasnet.ru (2009-07-23 13:35:44)
Пример не совсем рабочий, так как используется хелпер, html вместо form
217.118.91.104 (2009-07-24 11:52:44)
Cамый последний релиз на момент этой документации это Cake PHP? 1.0.1.2708.
Даже не читайте эту статью. Старье, работать не будет!
user-206.78.infomir.com.ua (2009-07-31 01:14:25)
Да статья не плохая, но уже не актуальная... просьба авторов изменить ее содеражание... а так для понимания работы фреймворка – самое то!
Для тех кто все же пытается, что то по ней написать предлагаю ссылочку
http://book.cakephp.org/view/189/Automagic-Form-Elements
95-83-36-224.saransk.ru (2009-08-05 15:07:53)
из всего того что здесь не работает – это только валидация – все абсолютно дееспособно если, как сказано выше, вместо хелпера html использовать form ну и расширения видов поменять с phtml на ctp
65.49.2.11 (2009-08-22 08:06:34)

как это? (у мя ошибочка вылетает, 512я)
77.79.180.60.dynamic.ufanet.ru (2009-10-18 03:39:49)
бугага... поржал над количеством тупого кода...
бля, сначала переводить научитесь и содержите
мануалы в порядке, а потом уже учите...

а то народ сидит – тупит
212-75-223-34.goodline.info (2009-10-26 02:12:26)
так то нормально, делал одновременно по данной и вот этой http://book.cakephp.org/ru/view/219/Blog
всё получилось.
/Ясен Пень? (2009-12-02 14:00:10)
ошибка, не findAll а find('all')
205-22-95-178.pool.ukrtel.net (2010-05-15 22:29:54)
Перевод и в правду кривой. Словно через промт делали и не читали, прежде чем запостить...

А сам фреймворк интересный – узнай я о нем по раньше – сэкономил бы много времени за написанием всяких мелких проектов. А так пришлось минидвижочек писать под эти нужды.
IamGikk (2010-08-26 07:28:38)
А можно как-нибудь правки в перевод вносить? Уж больно глаз режут выражения типа «как формулируются ссылки к».
IamGikk (2010-08-26 07:31:04)
не работает редактирование
нужно код в представление поменять на 
<h1>Edit Post</h1>
<form method="post" action="<?php echo $html->url('/posts/edit')?>">
<?php echo $form->hidden('id', array('value'=>$editpost['Post']['id'])); ?>
<p>
Title:
<?php echo $form->input('title', array('size' => '40', 'value'=>$editpost['Post']['title']))?>
</p>
<p>
Body:
<?php echo $form->textarea('body', array('rows'=>'10','value'=>$editpost['Post']['body'])) ?>
</p>
<p>
<?php echo $form->submit('Save') ?>
</p>
</form>

а в контроллере
function edit($id = null)
{
if (empty($this->data))
{
$this->Post->id = $id;
$this->set('editpost', $this->Post->read());
}
else
{
if ($this->Post->save($this->data))
{
$this->flash('Your post has been updated.','/posts');
}
}
}
212.13.136.30 (2011-01-19 10:01:28)
findAll() -> find('all') !!!
adsl-104.zp.velton.ua (2011-08-03 14:33:36)
Добавить комментарий:

Файлов нет. [Показать файлы/форму]