Контекст:
Мои вопросы относятся к форуму, который я разрабатываю почти так же, как SO, где есть:
- Гости, у кого есть доступ для просмотра тем, но не могут отвечать или голосовать
- члены, которые с достаточным количеством репутаций могут редактировать/голосовать за другие потоки, и по умолчанию они могут отвечать и иметь те же привилегии, что и гости
- администраторы, которые могут в значительной степени что-либо сделать
Я бы хотел, чтобы этот ACL был применен на весь сайт и по умолчанию запретил все ресурсы.
Я прочитал основы использования Zend_Acl - в том, что вы в основном создаете роли (guest, member, admin) и либо запрещаете, либо разрешаете ресурсы (контроллеры, методы) для этих ролей. Документация не очень конкретна в отношении того, как вы должны фактически реализовать acl-код в своем приложении, поэтому я пошел смотреть на SO..
Перешел через довольно полезный stackoverflow ответ от marek, который проливает свет на эту проблему, однако из-за моей незнакомости я все еще не могу полностью понять, как правильно реализовать это с учетом лучших практик.
Плакат имеет статический файл configAcl.php
в корне приложения, который инициализирует объект acl, добавляет роли, создает ресурс из каждого контроллера, предоставляет admin
доступ ко всему, предоставляет normal
доступ ко всем, кроме admin и сохраняет объект acl в реестре для последующего использования.
$acl = new Zend_Acl();
$roles = array('admin', 'normal');
// Controller script names. You have to add all of them if credential check
// is global to your application.
$controllers = array('auth', 'index', 'news', 'admin');
foreach ($roles as $role) {
$acl->addRole(new Zend_Acl_Role($role));
}
foreach ($controllers as $controller) {
$acl->add(new Zend_Acl_Resource($controller));
}
// Here comes credential definiton for admin user.
$acl->allow('admin'); // Has access to everything.
// Here comes credential definition for normal user.
$acl->allow('normal'); // Has access to everything...
$acl->deny('normal', 'admin'); // ... except the admin controller.
// Finally I store whole ACL definition to registry for use
// in AuthPlugin plugin.
$registry = Zend_Registry::getInstance();
$registry->set('acl', $acl);
Вопрос № 1. Должен ли этот код находиться в начальной загрузке или в автономном файле, например? Если бы это было бы лучше, если бы это было внутри, скажем, каталог библиотеки?
Вторая часть - это новый класс, расширяющий класс абстрактного плагина Zend Controller Abstract, который позволяет подключить его к auth/login
, логика в основном, если логин завершается с ошибкой, он перенаправляет.. в противном случае он захватывает объект acl из реестр, захватывает личность и определяет, разрешено ли пользователю просматривать этот ресурс.
$identity = $auth->getIdentity();
$frontController->registerPlugin(new AuthPlugin());
Вопрос № 2. Как точно я бы закодировал часть плагина auth, которая фактически возвращает идентификатор пользователя? Я понимаю, что у него был код ниже, который создавал объект таблицы db объекта Auth, который запрашивал бы столбец таблицы базы данных по идентификатору пользователя и учетным данным (проверка хэширования). Я смущен тем, где это вписывается в часть getIdentity.
Скажем, моя таблица пользователей состояла из этих данных:
user_id user_name level
1 superadmin 3
2 john 2
3 example.com 1
Где уровень 3 = admin, 2 = member, 1 = guest.
Вопрос № 3 - где именно хорошее место для размещения вышеуказанного кода аутентификации? Внутри контроллера входа?
Вопрос № 4 - еще один плакат отвечает своей статьей о том, как логика acl должна выполняться внутри моделей, но конкретный метод, который он использует, не поддерживается изначально и требует обходного пути, возможно ли это? И действительно ли это идеально должно быть сделано?