W poprzednim wpisie pokazałem jak można zastosować Zend_Auth do obsługi uwierzytelniania. Dzisiaj przykładowa aplikacja zostanie wzbogacona o kontrolę dostępu użytkowników, zrealizowaną z wykorzystaniem Zend_Acl.
Witryna będzie podzielona na trzy strefy:
- Pierwsza dostępna dla wszystkich użytkowników - strona główna, logowanie, rejestracja;
- druga - dostępna dla zalogowanych - "edycja profilu";
- trzecia - panel administracyjny.
Od strony aplikacji podział będzie następujący:
- Strefa pierwsza: moduł default, kontroler index, akcje index, login, register itp.;
- strefa druga: moduł default, kontroler index - akcja editProfile;
- strefa trzecia: cały moduł admin.
Rozbudowa szkieletu aplikacji
Zaczynamy od utworzenia nowych modułów, kontrolerów i akcji:
> zf create action register
> zf create action editProfile
> zf create module admin
> zf create controller index -m admin
Zend Framework musi wiedzieć w którym katalogu ma szukać modułów. Dopisujemy odpowiednią linię do sekcji [production] pliku application/configs/application.ini:
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
W tym momencie można sprawdzić czy moduł admin działa jak należy, wpisując w przeglądarce adres: http://localhost/aclauth/public/admin.
Budujemy listę kontroli dostępu
Pora zaprzęgnąć do pracy Zend_Acl. Zasoby muszą być zdefiniowane w taki sposób, aby można było łatwo przydzielać uprawnienia do poszczególnych modułów, kontrolerów i akcji:
$acl = new Zend_Acl();
$acl->addRole('guest');
$acl->addRole('member', 'guest'); // użytk. zalogowany dziedziczy uprawnienia gościa
$acl->addRole('admin');
$acl->addResource('default:index');
$acl->addResource('default:error');
$acl->addResource('admin:index');
$acl->allow('guest', 'default:index', 'index'); // goście mogą oglądać stronę główną...
$acl->allow('guest', 'default:index', 'login'); // ...zalogować się
$acl->allow('guest', 'default:index', 'register'); // zarejestrować
$acl->allow('guest', 'default:error'); // zobaczą też stronę z ew. komunikatem
// o błędzie
$acl->allow('member', 'default:index', 'logout'); // użytk. zalogowany może się wylogować...
$acl->allow('member', 'default:index', 'edit-profile'); // oraz edytować dane
$acl->allow('admin'); // wreszcie administrator - może przeglądać całą witrynę.
Aby sprawdzić czy użytkownik ma prawo oglądać daną podstronę wystarczy prosty kod:
$resource = $moduleName . ':' . $controllerName;
if (!$acl->isAllowed($role, $resource, $actionName)) {
throw new Exception('Nie masz dostępu do tej części witryny!');
}
Niech całość zostanie umieszczona w pluginie, zdefiniowanym w pliku application/plugins/Acl.php:
<?php
class Application_Plugin_Acl extends Zend_Controller_Plugin_Abstract
{
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
/* Lista kontroli dostępu */
$acl = new Zend_Acl();
$acl->addRole('guest');
$acl->addRole('member', 'guest');
$acl->addRole('admin');
$acl->addResource('default:index');
$acl->addResource('default:error');
$acl->addResource('admin:index');
$acl->allow('guest', 'default:index', 'index');
$acl->allow('guest', 'default:index', 'login');
$acl->allow('guest', 'default:index', 'register');
$acl->allow('guest', 'default:error');
$acl->allow('member', 'default:index', 'logout');
$acl->allow('member', 'default:index', 'edit-profile');
$acl->allow('admin');
/* Użytkownik */
$user = Zend_Auth::getInstance()->getIdentity();
if (null === $user) {
$role = 'guest';
} else {
$role = $user->role;
}
/* Czy użytkownik ma prawo dostępu? */
if (!$acl->isAllowed($role,
$request->getModuleName() . ':'
. $request->getControllerName(),
$request->getActionName())
) {
throw new Exception('Nie masz dostępu do tej części witryny!');
}
}
}
Ostatnim krokiem będzie dołączenie pluginu do aplikacji - w pliku application.ini:
resources.frontController.plugins.acl = Application_Plugin_Acl
Podsumowanie
W taki sposób napisaliśmy prostą aplikację umożliwiającą logowanie użytkowników oraz sprawdzającą uprawnienia. Polecam pobrać przykład i poeksperymentować - można dodać innych użytkowników lub nowe zasoby i sprawdzić jak to wszystko będzie razem działać.
Dobrym ćwiczeniem będzie też dodanie obsługi bazy danych, w której przechowywane będą dane użytkowników.