Sunday
16
May
autor:
Mateusz Tymek
kategorie:

Przykład zastosowania Zend_Auth i Zend_Acl - cz. 1

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.

 
Tagi: zend_form, zend_auth, uwierzytelnianie, zend_acl, zend_tool
Komentarze
snapshot 19 May 2010
Wszystko ok, tylko nie rozumiem, po co dodatkowo wrzucać identity do rejestru, skoro jest zawsze dostępny w Zend_Auth?
Mateusz Tymek 19 May 2010
Słuszna uwaga. Poprawiłem przykłady.
Samo trzymanie użytkownika w rejestrze to pewnego rodzaju "zaszłość" w kliku moich projektach :)
janiekj 29 May 2010
Coś chyba nie do końca jest dobrze... może tylko u mnie... ale wystarczy wpisać jakikolwiek login bez hasła ( poza zdefiniowanymi ) i loguje...
Mateusz Tymek 6 January 2010
Dzięki za zauważenie - poprawiłem :)
Podobne artykuły
Skomentuj artykuł

Nazwa użytkownika powinna składać się z conajmniej pięciu liter, cyfr i znaków podkreślenia. Powinna zaczynać się od litery.

Pole wymagane.
Adres e-mail nie zostanie pokazany publicznie.