Окт 09 2008

SimpleAcl — простой компонент для авторизации и проверки прав пользователей

Раздел: БезопасностьМета @ 23:42

В большинстве приложений необходимо не только отображать данные, но и взаимодействовать с пользователями. И даже не просто взаимодействовать, а по разному работать с разными группами. Даже в этом блоге — есть администраторы, есть зарегистрированные пользователи, а есть просто читатели. Чем админ отличается от обычного пользователя? Тем что у него есть доступ к определенным функциям. Как определить что пользователь — админ? Авторизовать его, узнать логин и пароль.

Эти задачи — авторизацию и определение прав доступа к различным функциям — приходится решать при разработке каждого сайта. В CakePHP есть встроенный компонент Acl для работы с правами, но он слишком навороченный для простых сайтов. Часто, если надо просто ограничить доступ к админке, мы в своей студии используем простой ValidationComponent, единственное что модифицированный под использование Http-Digest авторизации.

В случаях же когда надо и авторизовать, и проверять права, можно использовать SimpleAcl-компонент. Я наткнулся на него в Пекарне.

Например, у нас есть база данных кадрового агентства. У каждого соискателя есть фотография, краткое резюме, набор навыков и контактные данные. Неавторизованные пользователи могут просматривать базу данных, фотографии, искать и отбирать по навыкам, но не видят контактных данных. Зарегистрированные пользователи — видят контакты. А администраторы — могут не только просматривать базу, но и добавлять новых соискателей. Допустим, все контроллеры и функции для просмотра, поиска и редактирования базы уже созданы.

Копируем SimpleAcl-компонент в папку /app/controllers/components/.

Создаем файл /app/app_controller.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
class AppController extends Controller {
    var $components = array('SimpleAcl', 'Auth');
 
    function beforeFilter() {
        parent::beforeFilter();
 
        if (isset($this->Auth)) {
            // Устанавливаем тип авторизации
            $this->Auth->authorize = 'object';
 
            // Передаем в стандартный AuthComponent указатель на объект, который будет разрешать и проверять авторизацию
            $this->Auth->object = &$this->SimpleAcl;
            // Получаем разрешенные действия для текущего контроллера
            if($this->action != 'login' && ((empty($this->access) || !array_key_exists($this->action, $this->access))) && empty($this->params[Configure::read('Routing.admin')])) {
                $this->Auth->allow();
            }
 
            // Все остальные настройки не обязательны — можно смело использовать проставленные по-умолчанию
            // дополнительные условия для запроса поиска пользователей.
            //$this->Auth->userScope = array('User.verified' => 1);
            // функция для запроса логина-пароля от пользователя (по-умолчанию '/users/login')
            $this->Auth->loginAction = '/users/login';
            // текст сообщения о неправильном логине-пароле
            $this->Auth->loginError = 'Неправильный логин или пароль, попробуйте снова.';
            // текст сообщения, когда у пользователя недостаточно прав
            $this->Auth->authError = 'Доступ запрещен.';
            // куда редиректить после успешной авторизации
            $this->Auth->loginRedirect = '/actors';
	// куда редиректить после выхода
	$this->Auth->logoutRedirect = '/actors';
            // имя модели, в которой хранятся логины и пароли (по-умолчанию 'User')
            $this->Auth->userModel = 'User';
            // поля таблицы, содержащие логин и пароль (надо указать оба поля)
            $this->Auth->fields = array('username' => 'username', 'password' => 'password');
	// переменная, в которой информация об авторизованном пользователе передается в шаблон
	$this->set('logged_user', $this->Auth->user());
        }
    }
}
?>

Создаем таблицу и модель для хранения пользователей:

1
2
3
4
5
6
7
CREATE TABLE IF NOT EXISTS `users` (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `username` varchar(64) NOT NULL,
  `password` varchar(64) NOT NULL,
  `role` varchar(50) NOT NULL DEFAULT 'User',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM;
1
2
3
4
5
6
7
<?php
class User extends AppModel {
 
	var $name = 'User';
 
}
?>

Создаем контроллер users_controller.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
class UsersController extends AppController {
 
	var $name = 'Users';
	var $helpers = array('Html', 'Form'); 
 
    function login() {
    }
 
    function logout() {
        $this->redirect($this->Auth->logout());
    }
 
}
?>

Сейчас он нужен только для авторизации и завершения сессии пользователей. Но естественно, для удобства в нем надо написать функции для редактирования пользователей.

Создаем шаблон с формой входа /app/views/users/login.ctp:

1
2
3
4
5
6
7
8
<h1>Вход в систему</h1>
<?php
    if  ($session->check('Message.auth')) $session->flash('auth');
    echo $form->create('User', array('action' => 'login'));
    echo $form->input('username', array('label' => 'Имя пользователя'));
    echo $form->input('password', array( 'label' => 'Пароль'));
    echo $form->end('Войти');
?>

На этом установка компонента закончена, можно начинать использовать.

В тех контроллерах, где нам надо ограничить доступ к некоторым функциям добавляем массив $access:

1
2
3
4
5
6
7
8
9
10
11
<?php
class PeopleController extends AppController {
 
	var $name = 'People';
	var $helpers = array('Html', 'Form');
 
    var $access = array(
        'search' => array('User','Admin'),
    ); 
 
...

В этом массиве ключи — это названия функций к которым надо ограничить доступ (в примере — функция search), а значения — вложенные массивы со списком разрешенных групп пользователей. В таблице users группа пользователя указывается в поле ‘role’.

Все, после этих действий SimpleAcl будет отшибать неавторизованных пользователей от закрытых функций.

Естественно, где-то на сайте надо сделать ссылку на форму входа и для выхода, например так:

1
2
3
4
5
6
7
8
9
<?php if (!empty($logged_user)) { ?>
<div id="login">
    <?php echo $html->link(__('Выход', true), '/users/logout'); ?>
</div>
<?php } else { ?>
<div id="login">
    <?php echo $html->link(__('Войти', true), '/users/login'); ?>
</div>
<?php } ?>

В шаблонах можно проверять группу пользователя и отображать/скрывать некоторые блоки:

1
2
3
4
5
 <?php if (!empty($logged_user) && ($logged_user['User']['role'] == 'Admin')) { ?>
<div id="create_new_actor">
    <?php echo $html->link(__('Добавить нового соискателя', true), '/people/add'); ?>
</div>
<?php } ?>

Теги: , , , , ,

4 Responses to “SimpleAcl — простой компонент для авторизации и проверки прав пользователей”

  1. Николай says:

    спасибо :)

  2. xain says:

    Я конечно с CakePHP новичок, но почемуто в файле login.ctp не хочет вызывать методы $form
    Call to undefined function: create()

    подскажите пожалуйста почему, где я настройки не доставил

  3. Мета says:

    Добавьте в начале вашего контроллера:
    var $helpers = array(’Html’, ‘Form’);

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

  4. гость says:

    забыли указать, что SimpleAcl-компонент должен называться auth.php

Напиши комментарий!