Przykład zastosowania Zend_Auth i Zend_Acl - cz. 2

by Mateusz Tymek — on Zend Framework, PHP

Head's up! This post was written back in 2010 and is very likely to contain outdated information.

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.

Pobierz przykład.


comments powered by Disqus