Рассмотренный нами ранее модуль Auth неплох, но недавно на форуме сообщили о создании более простого модуля аутентификации с незамысловатым названием A1. Он представляет собой облегченную версию Auth — без лишней абстракции и драйверов (т.е. мы просто явно используем ORM), без ролей (точнее роли есть, но они теперь не являются отдельными от пользователя объектами). Кроме данного модуля предлагается портированная Zend‘овская библиотека Zend_Acl и созданный на ее основе модуль авторизации A2.
Для начала необходимо поработать над модулями, т.к. они были созданы под 3.0 со всеми сопутствующими препятствиями (иная структура папок, именование классов и еще несколько мелочей). Итоговый архив с небольшими доработками можно скачать тут. Модули разбиты на три папки, но в принципе их можно объединить в одну.
Настройка
Скопируйте модули и контроллер в соответствующие папки. В application/config/config.php не забудьте подключить модули. Кроме того, рекомендую закомментировать модуль Auth и проверить, нет ли в application/models моделей Auth и Blog (они присутствуют в модуле A2), т.к. они будет загружены вместо необходимым нам. Для работы прилагаемого демо-контроллера необходимы две таблицы, одна для пользователей, другая для контролируемого ресурса (блоги):
CREATE TABLE IF NOT EXISTS `users` ( `id` INT(12) UNSIGNED NOT NULL AUTO_INCREMENT, `username` VARCHAR(32) NOT NULL DEFAULT '', `password` CHAR(50) NOT NULL, `logins` INT(10) UNSIGNED NOT NULL DEFAULT '0', `last_login` INT(10) UNSIGNED DEFAULT NULL, `role` enum('user','admin') NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uniq_username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `blogs` ( `id` INT(12) UNSIGNED NOT NULL AUTO_INCREMENT, `user_id` INT(12) UNSIGNED NOT NULL, `text` text NOT NULL, PRIMARY KEY (`id`), KEY `user_id` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
Поскольку таблица с пользователями у меня уже была, я просто добавил поле `role` и убрал в существующем поле `email` атрибут NOT NULL (данное поле в демо использоваться не будет). Если таблица `users` у вас тоже есть, не забудьте в файле modules/a1/config/a1.php привести настройки (метод хэширования, «соль» и т.д.) в соответствие с теми, что были в auth.php (он либо в application/config/, либо в modules/auth/config).
Вот собственно и все. Запускаем http://localhost/a2demo/ и видим предложение представиться/зарегистрироваться, а также сообщение, что блогов нет. Сперва войдем на сайт под существующем логином или зарегистрируемся. Тут все более-менее похоже на модуль Auth, разве что в выводимой Profiler‘ом информации на удивление мало запросов, связанных с пользователем (как мы помним, Auth делал три запроса).
Управление объектами
Так для чего же нам нужны эти две дополнительные библиотеки? Если вы еще не знакомы с Zend_Acl, самое время немного почитать. В общих чертах, Acl (списки доступа) — это некий набор типовых правил («разрешить то-то»/»запретить то-то»), применяемых к отдельным классам ресурсов (в нашем случае это блоги) для текущего пользователя (точнее, для имеющихся у пользователя ролей). Так, в конфигурационном файле a2.php приведены правила следующего вида:
$config['rules'] = array ( 'allow' => array ( // guest can read blog array('guest','blog','read'), ... ), ... } |
Первый параметр — роль, второй — класс ресурса, далее имя операции. Все это разрешается (т.к. ключ «allow«). Аналогично существуют правила для запрета операций. Кроме того, роли пользователей выполнены в виде иерархии Гость->Пользователь->Админ с наследованием правил. Еще одна возможность — использование утверждений (asserts). Это правила с добавлением условий их применения (таким образом реализована проверка владельца блога при редактировании). Все правила загружаются из файла, а не из БД, хорошо это или плохо — решать вам. Мне кажется, с разрастанием приложения могут возникнуть проблемы…
А что насчет A2? Дело в том, что нас не всегда устраивают разрешения для целого класса ресурсов. Для отдельных экземпляров объектов в A2 можно применить отдельные правила. Для этого вместо строкового названия ресурса можно использовать экземпляр конкретного ресурса (например, ORM::factory(‘blog’,1), т.е. блог с идентификатором 1).
Помимо настроек в конфигурационном файле мы можем редактировать правила прямо в демо-контроллере:
// разрешаем редактирование всех блогов админами $this->a2->allow('admin', 'blog', 'edit', NULL); // добавляем для пользователей право на удаление блога с id=1 $this->a2->allow('user', ORM::factory('blog', 1), 'delete', NULL); // запрещаем чтение блогов ВСЕМ пользователям (правила наследуются) $this->a2->deny('guest', 'blog', 'read', NULL); |
Итог
Получилось несколько сумбурно, но, надеюсь, что основную мысль я до вас донес. В любом случае скоро нам придется попробовать применить данный модуль вместо тяжеловесного Auth. И если не выявится еще какой-либо более интересный модуль, мы будем использовать именно связку A1+A2.
PS. В настоящее время имеется полноценная и развивающаяся версия данного модуля на гитхабе для ветки 2.3.
Раньше постоянно работал с Auth. Не такой уж тяжеловесный, если ему прикрутить кеширование. Но это надо сильно с кодом помараться, почти весь драйвер переписывать. Я бралса за это дело, но не довел до конца.
Посмотрим на альтернативные решения. Спасибо.
В принципе A2 может и с Auth работать, общие корни наверное сказываются