Przykład zastosowania Zend_Auth i Zend_Acl - cz. 1

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.

Uwierzytelnianie i autoryzacja w Zend Framework: Zend_Auth i Zend_AclW artykule przedstawię "przepis" na zbudowanie prostej aplikacji wykorzystującej Zend_Auth do logowania, oraz - w drugiej części - Zend_Acl do kontroli dostępu użytkowników.

Na potrzeby artykułu zakładam że w naszym systemie posiadamy ZF w wersji 1.10.4, oraz że Zend_Tool jest poprawnie skonfigurowany.

Szkielet projektu

Tworzymy nowy projekt i przechodzimy do odpowiedniego podkatalogu:

> zf create project aclauth
Creating project at /home/mateusz/public_html/aclauth
Note: This command created a web project, for more information setting up your VHOST, please see docs/README

> cd aclauth

Dodajemy potrzebne akcje i tworzymy formularz logowania oraz model użytkownika:

> zf create action login
> zf create action logout
> zf create form login
> zf create model user

Formularz logowania

Formularz utworzony przez Zend_Tool jest tak naprawdę klasą z pustą metodą init(). Sami musimy zadbać o utworzenie odpowiednich elementów.

Edytujemy plik application/forms/Login.php w którym definiujemy elementy formularza:

<?php

class Application_Form_Login extends Zend_Form
{
    public function init()
    {        
        $this->addElement('text', 'login', array(
            'filters' => array(
                'StringTrim'
            ),
            'label' => 'Login:'
        ));
        $this->addElement('password', 'password', array(
            'label' => 'Hasło:'
        ));
        $this->addElement('submit', 'submit', array(
            'ignore' => true,
            'label' => 'Zaloguj'
        ));
    }
}

Model użytkownika

W pliku application/models/User.php znajduje się kolejna pusta klasa którą utworzył
Zend_Tool.
Nasz użytkownik będzie posiadał trzy własności: login, hasło oraz "rolę".
"Rola" zadecyduje o uprawnieniach użytkownika. Może przyjąć trzy różne wartości:

  • guest - niezalogowany użytkownik
  • member - zarejestrowany i zalogowany użytkownik
  • admin - administrator

Dodajmy te pola oraz pustą metodę authenticate do klasy:

<?php
class Application_Model_User implements Zend_Auth_Adapter_Interface
{

    public $login;
    public $password;
    public $role;

    public function authenticate()
    {
    }
}

Zadaniem metody authenticate() jest sprawdzenie poprawności loginu i hasła. W prawdziwej aplikacji w tym miejscu nastąpi połączenie z bazą danych i znalezienie w niej odpowiedniego użytkownika. Jednak aby uprościć przykład dozwoleni użytkownicy zostaną zapisani na sztywno w kodzie:

<?php
class Application_Model_User implements Zend_Auth_Adapter_Interface
{

    protected $_users = array(
        'user1' => array('password' => 'pass1', 'role' => 'member'),
        'user2' => array('password' => 'pass2', 'role' => 'member'),
        'user3' => array('password' => 'pass3', 'role' => 'member'),
        'admin' => array('password' => 'pass4', 'role' => 'admin')
    );

(...)

Logowanie będzie odbywać się w następujący sposób:

  1. Utworzenie obiektu klasy Application_Model_User
  2. Wpisanie do niego danych z formularza logowania
  3. Wywołanie metody Zend_Auth::authenticate...
  4. ... która wywoła metodę authenticate() naszego Usera

Wreszcie ta ostatnia metoda sprawdzi czy login danego użytkownika zgadza się z hasłem.

Oto kod akcji "login":

public function loginAction()
{
    $form = new Application_Form_Login();
    $request = $this->getRequest();
    if ($request->isPost()) {
        if ($form->isValid($request->getPost())) {
            $user = new Application_Model_User();
            $user->login = $form->getValue('login');
            $user->password = $form->getValue('password');
            $result = Zend_Auth::getInstance()->authenticate($user);
            if ($result->isValid()) {               
                $this->_helper->redirector('index');
            } else {
                $form->login->addError('Podano niepoprawny login i/lub hasło.');
            }
        }
    }

    $this->view->loginForm = $form;
}

Metoda authenticate() modelu użytkownika:

public function authenticate()
{
    if (!isset($this->_users[$this->login])
        || $this->_users[$this->login]['password'] != $this->password) {
        $result = new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, null);
    } else {
        $this->role = $this->_users[$this->login]['role'];
        $result = new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $this);
    }
    return $result;
}

W tym miejscu mamy pewność że zalogowany użytkownik będzie dostępny poprzez Zend_Auth:

 


Zend_Auth::getInstance()->getIdentity();

Obsługa wylogowania użytkownika jest bardzo proste i polega na wywaołaniu odpowiedniej metody Zend_Auth:

public function logoutAction()
{
    Zend_Auth::getInstance()->clearIdentity();
    $this->_helper->redirector('index');
}

Ostatnia formalność to widoki. Potrzebujemy dwóch - pierwszy (strona główna) wyświetli informację czy użytkownik jest zalogowan, a drugi - formularz logowania.

application/views/scripts/index/index.phtml:

<h1>Strona Główna</h1>
<?php

$user = Zend_Auth::getInstance()->getIdentity();

if (null !== $user) {

    echo 'Jesteś zalogowany jako ' . $user->login . '<br />';
    echo '<a href="' . $this->url(array('action' => 'logout')) . '">Wyloguj się</a>';

} else {
    echo 'Nie jesteś zalogowany<br />';
    echo '<a href="' . $this->url(array('action' => 'login')) . '">Zaloguj się</a>';
}

application/views/scripts/index/login.phtml:

<h1>Logowanie</h1>

<?php echo $this->loginForm ?>

Przykład gotowy - można uruchomić go w przeglądarce.

Pobierz przykład.


comments powered by Disqus