Utilizzare Zend_Auth_Adapter per il login

Ciao Gianni, essendo questa la prima volta che lavoro con un framework, leggendo il tuo articolo sto riuscendo a fare qualcosina  ;D

ho visto che posso fare le cose basilari, ma ora vorrei implementare un sistema di autenticazione utilizzando lo Zend_Auth_Adapter ( table ), solo che non so come va implementata la vista e il modello e il controller per il login ... come devo fare?

Devo fare le viste/controller e modello anche per quelli o posso creare delle viste indipendenti  da includere nelle viste principali con render() ?

confused, che sonno!!! :buck:

 :bye:

inviato 9 anni fa
Andrea Turso
Andrea Turso
86
X 0 X

risolto, era più facile di quanto pensassi :

/views
    /customers
            index.phtml
            login.phtml
            panel.pthml
            logout.phtml

giusto una domanda : dove inizializzo l'auth adapter ? nel file di bootstrap???

   $auth = new Zend_Auth_Adapter_DbTable($db, 'users', 'name', 'pass');

lo devo mettere nel CustomersController o in index.php?

come controllo se l'utente è loggato o no con questo adapter?

:bye:

risposto 9 anni fa
Andrea Turso
Andrea Turso
86
modificato 9 anni fa
X 0 X

OK inizializzato in index e regisrato con Zend_Registry in modo da potergli accedere dovunque.

risposto 9 anni fa
Andrea Turso
Andrea Turso
86
X 0 X

Gianni come faccio a creare una sessione persistente ( cookie o sessione ) con lo Zend_Auth

ho scritto questo codice per la gestione del login :

Customers.php

<?php
class Customers
{
   function userLogin($username, $password)
   {
      $auth = Zend_Registry::get('auth');
      $auth->setIdentity($username)
          ->setCredential($password);
      
      return $result = $auth->authenticate();
   }
}

CustomersController.php

<?php
class CustomersController extends Zend_Controller_Action
{
   public function init()
   {
        /********* questo metodo l'ho copiato pari pari dal tuo tutorial , cosa fa ??? ***/
      $this->_flashMessenger = $this->_helper->getHelper('flashMessenger');
      
      if($this->_hasParam('annulla')) {
         $this->_redirect('/');
      }
   }
   
   public function indexAction()
   {
      $this->view->title = 'asd';
      $customers = new Customers;
   }
   public function loginAction()
   {
      $customers = new Customers;
      
      $this->view->title = 'Login';   
      $filter = new Zend_Filter();
      $filter->addFilter(new Zend_Filter_Alnum())
            ->addFilter(new Zend_Filter_StringToLower());
            
      if(isset($_POST['submit'])) {
         $username = $filter->filter($_POST['username']);
         $password = $filter->filter($_POST['password']);
         $result = $customers->userLogin($username, $password);
         echo $username;
         switch ( $result->getCode() ) {
            case -3 :
               $this->view->username = $result->getIdentity();
               $this->view->errorMessage = 'Supplied password is not correct';
               break;
            case -1 :
               $this->view->errorMessage = 'Username not found';
               break;
            case 1  :
               header('location: /customers/panel/');
               break;
            default :
               return 'Unknown error';
               break;
         }
      }
   }
   
   public function registerAction()
   {
         /****/
   }
}

lo Zend_Auth è instanziato nel file di bootstrap:

index.php

<?php
set_include_path(get_include_path().';'.'C:\Programmi\Apache Group\Apache2\htdocs\sms3\application\library\\'.';'.'.\application\models');

require_once 'Zend/Loader.php';

Zend_Loader::registerAutoload();

date_default_timezone_set('Europe/Rome');

try {
   $options = array(
   'host'     => 'localhost',
   'username' => 'root1',
   'password' => 'ppixellol',
   'dbname'   => 'sms'
   );
   $db = Zend_Db::factory('Pdo_Mysql', $options);
   $db->getConnection();
      
   $auth = new Zend_Auth_Adapter_DbTable($db, 'users', 'name', 'pass');
   $acl  = new Zend_Acl();
   
   $acl->addRole(new Zend_Acl_Role('guest'));
   $acl->addRole(new Zend_Acl_Role('registred'));
   $acl->addRole(new Zend_Acl_Role('administrator'));
   
   $acl->allow('guest', null, 'view');
   $acl->allow('administrator');
       
} catch (Zend_Auth_Adapter_Exception $e) {
   die("Errore durante l'istanziazione del sistema di autenticazione: ".$e->getMessage());   
} catch (Zend_Db_Adapter_Exception $e) {
   die("Zend_Db_Adapter_Exception: ".$e->getMessage());
} catch (Zend_Exception $e) {
   die("Zend_Exception".$e->getMessage());
}
Zend_Registry::set('auth', $auth);
Zend_Registry::set('db', $db);

define('BASE_URL', str_replace('index.php','',$_SERVER['PHP_SELF']));
Zend_Controller_Front::run('application/controllers');

PS : Come uso Zend_Acl con Zend_Auth in modo che siano gestiti anche i permessi ??

devo salvare il rank dell'utente nel database e poi fare cosa???

 :bye:

risposto 9 anni fa
Andrea Turso
Andrea Turso
86
modificato 9 anni fa
X 0 X

quando lanci $auth->authenticate() viene automaticamente salvato in sessione l'esito dell'autenticazione, non devi preoccuparti di nulla! Puoi anche aggiungere altre informazioni sull'utente loggato in modo che anche queste restino persistenti.

Nelle successive richieste per verificare se l'utente è loggato basta verificare $auth->hasIdentity() mentre per il logout: $auth->clearIdentity();

Tieni presente che l'oggetto Zend_Auth è un singleton per cui per ottenerlo in qualsiasi parte del cotice ti basta chiamare $auth = Zend_Auth::getInstance()

 :bye:

risposto 9 anni fa
Gianni Tomasicchio
X 0 X

qundi posso evitare di usare Zend_Registry ?

risposto 9 anni fa
Andrea Turso
Andrea Turso
86
X 0 X

Gianni, dimmi un po se sto facendo tutto bene :

Customers.php

<?php
class Customers
{
   private $_auth;
   private $_db;
   private $_authAdapter;
   
   function __construct()
   {
      $this->_db    = Zend_Registry::get('db');
      $this->_auth= Zend_Auth::getInstance();
      $this->_authAdapter = new Zend_Auth_Adapter_DbTable($this->_db, 'users', 'name', 'pass');
   }
   
   function userLogin($username, $password)
   {      
      
      $this->_authAdapter ->setIdentity($username)
                       ->setCredential($password);
      
      return $this->_authAdapter->authenticate( $this->_authAdapter );
   }
   
   function isIdentified()
   {
      return $this->_auth->hasIdentity();
   }
}

CustomersController.php

<?php
class CustomersController extends Zend_Controller_Action
{
   public function indexAction()
   {
      $customers = new Customers;
      
      if ($customers->isIdentified()) {
         //utente loggato, mostro il pannello
      } else {
         //utente non loggato , mostra il login
      }
   }
   
   public function loginAction()
   {
      $customers = new Customers;
      
      $this->view->title = 'Login';   
      $filter = new Zend_Filter();
      $filter->addFilter(new Zend_Filter_Alnum())
            ->addFilter(new Zend_Filter_StringToLower());
            
      if(isset($_POST['submit'])) {
         $username = $filter->filter($_POST['username']);
         $password = $filter->filter($_POST['password']);
         $result = $customers->userLogin($username, $password);
         
         switch ($result->getCode()) {
         
            case -3:            
               $this->view->username = $result->getIdentity();
               $this->view->errorMessage = 'Supplied password is not correct';
               break;
               
            case -1:            
               $this->view->errorMessage = 'Username not found';
               break;
               
            case 1:            
               $this->view->render('panel.phtml');
               break;
               
            default :            
               return 'Unknown error';
               break;
         }
      } else if ( $customers->isIdentified() ) {
         $this->view->title = "logged";
      }
   }
   
   public function registerAction()
   {
      //registrazione utente
   }
}
risposto 9 anni fa
Andrea Turso
Andrea Turso
86
X 0 X

Si, mi sembra tutto Ok, magari la classe Customers non è poi così necessaria ma va bene.

 :bye:

risposto 9 anni fa
Gianni Tomasicchio
X 0 X

mmh, perchè non è necessaria ???

Non so proprio dove mettere il codice del login... ;D

Gianni non riesco a verificare se è autenticato o no!!! come devo fare???

:bye:

risposto 9 anni fa
Andrea Turso
Andrea Turso
86
X 0 X

Gianni come devo fare???

Sembra che non crei nessuna sessione la classe Zend_Auth... non riesco a capire perchè.

risposto 9 anni fa
Andrea Turso
Andrea Turso
86
X 0 X

Perfetto ci sono riuscito, ho capito che posso usare il controller senza per forza avere la classe del modello :P

ecco qui la soluzione, nel caso servisse a qualcuno :

CustomersController.php

<?php
class CustomersController extends Zend_Controller_Action
{
   public function indexAction()
   {
      $db = Zend_Registry::get('db');
      $auth = Zend_Auth::getInstance();
      $adapter = new Zend_Auth_Adapter_DbTable($db, 'users', 'name', 'pass', 'SHA1(?)');
      
      if ($auth->hasIdentity()) {
         $this->_redirect('/customers/panel/');
      } else {
         $this->_redirect('/customers/login/');
      }
   }
   
   public function loginAction()
   {   
      $db = Zend_Registry::get('db');
      $auth = Zend_Auth::getInstance();
      $adapter = new Zend_Auth_Adapter_DbTable($db, 'users', 'name', 'pass', 'SHA1(?)');
      
      $this->view->title = 'Login';
         
      $filter = new Zend_Filter();
      $filter->addFilter(new Zend_Filter_Alnum())
            ->addFilter(new Zend_Filter_StringToLower());
            
      if(isset($_POST['submit'])) {
         $username = $filter->filter($_POST['username']);
         $password = $filter->filter($_POST['password']);

         $adapter->setIdentity($username)
               ->setCredential($password);   
                     
         $result = $auth->authenticate($adapter);
         
         switch ($result->getCode()){
            case Zend_Auth_Result::SUCCESS :
               $this->_redirect('/customers/panel');
               break;
            
            case Zend_Auth_Result::FAILURE :
               $this->view->errorMessage = 'Error during login attempt';
               break;
               
            case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND :
               $this->view->errorMesasge = 'Username not found';
               break;
               
            case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID :
               $this->view->username = $result->getIdentity();
               $this->view->errorMessage = 'Wrong password';
               break;
            
            case Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS :
               $this->view->errorMessage = 'Ambiguous identity';
               break;
            
            default:
               $this->view->errorMessage = 'An unknown error has accoured during login attempt';
               break;
         }
      }
   }
   
   public function logoutAction()
   {
      $db = Zend_Registry::get('db');
      $auth = Zend_Auth::getInstance();
      $adapter = new Zend_Auth_Adapter_DbTable($db, 'users', 'name', 'pass', 'SHA1(?)');
      
      if ($auth->hasIdentity()) {
         if($auth->clearIdentity()){
            $this->view->message = array('success','You were successfully logged out.');
         } else {
            $this->view->message = array('error','Error during logout attempt.');
         }
      } else {
         $this->_redirect('/customers/login/');
      }   
   }
   
   public function panelAction()
   {
   }
   
   public function registerAction()
   {
   }
}

:bye:

risposto 9 anni fa
Andrea Turso
Andrea Turso
86
X 0 X

nei controller puoi usare il metodo init() per mettere le istruzioni da eseguire qualsiasi Action venga poi richiamata. Ad esempio potresti mettere lì le istruzioni

$db = Zend_Registry::get('db');

$auth = Zend_Auth::getInstance();

$adapter = new Zend_Auth_Adapter_DbTable($db, 'users', 'name', 'pass', 'SHA1(?)');

ovviamente le variabili locali dovrebbero diventare delle variabili membro.

 :bye:

P.S.: visto che sei riuscito a fare lo script di login, ti andrebbe di scrivere un articolo a riguardo?

risposto 9 anni fa
Gianni Tomasicchio
X 0 X

Certo Gianni, ne sarei molto felice!!!

Domani inizio a scrivere qualcosa dopo il lavoro!

ci sentiamo via pm

risposto 9 anni fa
Andrea Turso
Andrea Turso
86
X 0 X
Effettua l'accesso o registrati per rispondere a questa domanda