Zend Framework Login

Preparando il Database
La pagina di login è una parte importante per un’applicazione con un database. In questo capitolo, parleremo di come creare semplice sistema di accesso con Zend Framework. Ci sono diversi scenari possibili, ma si sceglierà il login con il database. Questo vuol dire che abbiamo bisogno di un database per memorizzare i dati dei membri.
Useremo ancora lo stesso database dell’esercizio precedente. Il nome del database è “zend“. Ora, creare la tabella per memorizzare le informazioni membri. Il nome della tabella è “users“. È possibile utilizzare la seguente query:
Copia codice

CREATE TABLE `users` (
  `id` int(11) NOT NULL auto_increment,
  `username` varchar(50) NOT NULL,
  `password` varchar(255) NOT NULL,
  `real_name` varchar(50) NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `username` (`username`)
);
Ora, provate a inserire i dati di un membro come campione, ad esempio:
Copia codice

INSERT INTO `users`
(`id`, `username`, `password`, `real_name`)
VALUES
(1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 'Administrator');
Nella query di sopra, inseriamo un membro con il nome utente “admin”. In realtà, la sua password è admin. Ma, per motivi di sicurezza, si usa MD5(), per questo motivo, la password che viene memorizzata nel database diventa 21232f297a57a5a743894a0e4a801fc3.
Copia codice

INSERT INTO `users` (`id` ,`username` ,`password` ,`real_name`)
VALUES (NULL , 'admin', MD5( 'admin' ) , 'Administrator');
Questa è l’immagine se usiamo phpMyAdmin.
create user for zend framework login system
Creazione Login Form
Per costruire sistema di login, abbiamo bisogno di form per il login. In questo post, impareremo a costruire semplice form per il login.
In primo luogo, creare un file denominato “loginform.phtml” sotto la cartella application/views/scripts/user. Inserire il seguente codice:
Copia codice

<? include "header.phtml"; ?>
  <h1><?=$this->escape($this->title);?></h1>
  <form method='post' action='<?=$this->escape($this->action);?>'>
  <table>
    <tr>
	  <td><?=$this->escape($this->username);?></td>
	  <td><input type='text' name='username'></td>
	</tr>
    <tr>
	  <td><?=$this->escape($this->password);?></td>
	  <td><input type='password' name='password'></td>
	</tr>
  </table>
  <input type='submit' name='login' value='Login'>
  </form>
<? include "footer.phtml"; ?>
Successivamente, creare loginformAction al controller. Aprire il file UserController.php sotto la cartella application/controllers. Aggiungi il metodo loginFormAction():
Copia codice

  public function loginformAction()
  {
    $request = $this->getRequest();
	$this->view->assign('action', $request->getBaseURL()."/user/auth");
    $this->view->assign('title', 'Login Form');
    $this->view->assign('username', 'Nome Utente');
    $this->view->assign('password', 'Password');
  }
Questo form invia due parametri: username e password. Essi vengono inviati alla pagina user/auth.
Ora, puntare il browser su http://localhost/test/zend/ciaoMondo/web_root/user/loginform. Si ottiene qualcosa come questo:

Creazione di autenticazione
Dopo la creazione del form di login, abbiamo bisogno dell’autenticazione. I dati verranno controllati con i dati esistenti al database.
Basta ricordare, che form di login invia due parametri: username e password. Essi vengono inviati alla pagina user/auth. Quindi, dobbiamo costruire il metodo authAction() in UserController.
authAction() serve per la convalida dei dati. I dati inviati dal modulo di login saranno verificate a authAction(). Aprite il file “UserController.php“. Prima, caricare Zend/Auth.php e Zend/Auth/Adapter/DbTable.php. Quindi includere all’inizio prima di ogni metodo():
Copia codice

<?php
require_once 'Zend/Auth.php';
require_once 'Zend/Auth/Adapter/DbTable.php';
...
?>
Aggiungere authAction() come segue:
Copia codice

<?php
  public function authAction(){
    $request 	= $this->getRequest();
    $registry 	= Zend_Registry::getInstance();
	$auth		= Zend_Auth::getInstance(); 
	$DB = $registry['DB'];
    $authAdapter = new Zend_Auth_Adapter_DbTable($DB);
    $authAdapter->setTableName('users')
    ->setIdentityColumn('username')
    ->setCredentialColumn('password');    
	// Impostare i valori di input delle credenziali
	$uname = $request->getParam('username');
	$paswd = $request->getParam('password');
    $authAdapter->setIdentity($uname);
    $authAdapter->setCredential(md5($paswd));
    // Eseguire la query di autenticazione
    // salvando il risultato
    $result = $auth->authenticate($authAdapter);
    if($result->isValid()){
	  $data = $authAdapter->getResultRowObject(null,'password');
	  $auth->getStorage()->write($data);
	  $this->_redirect('/user/userpage');
	}else{
	  $this->_redirect('/user/loginform');
	}
 }
In primo luogo, carichiamo l’adattatore del database dal registro di sistema (linee 3, 6). Se ancora non si capisce questo codice, si prega di leggere i capitoli su Zend Framework Database e Zend Framework Registry.
Poi, defininiamo l’adattatore per l’autenticazione:
Copia codice

$authAdapter = new Zend_Auth_Adapter_DbTable($DB);
Quindi, possiamo definire il nome della tabella e la colonna che contiene username e password.
Copia codice

    $authAdapter->setTableName('users')
    ->setIdentityColumn('username')
    ->setCredentialColumn('password');
Quindi, prendiamo i parametri HTTP che contengono username e password:
Copia codice

	$uname = $request->getParam('username');
	$paswd = $request->getParam('password');
    $authAdapter->setIdentity($uname);
    $authAdapter->setCredential(md5($paswd));
Quindi, fare l’autenticazione:
Copia codice

    $result = $auth->authenticate($authAdapter);
    if($result->isValid()){
	  $data = $authAdapter->getResultRowObject(null,'password');
	  $auth->getStorage()->write($data);
	  $this->_redirect('/user/userpage');
	}else{
	  $this->_redirect('/user/loginform');
	}
 }
Se l’utente è valido, salveremo i dati dell’utente durante la sessione utilizzando:
Copia codice

	  $data = $authAdapter->getResultRowObject(null,'password');
	  $auth->getStorage()->write($data);
Poi, pagina sarà reindirizzata alla pagina protetta (chiamata pagina utente in questo tutorial). Prossimo post, parleremo di pagina protetta. È semplice, non è vero?
Ok, questo è il nostro metodo UserController completo:
Copia codice

<?php
require_once 'Zend/Controller/Action.php';
require_once 'Zend/Auth.php';
require_once 'Zend/Auth/Adapter/DbTable.php';
class UserController extends Zend_Controller_Action
{
  public function loginFormAction()
  {
    $request = $this->getRequest();
	$this->view->assign('action', $request->getBaseURL()."/user/auth");
    $this->view->assign('title', 'Login Form');
    $this->view->assign('username', 'Nome Utente');
    $this->view->assign('password', 'Password');
  }
  public function authAction(){
    $request 	= $this->getRequest();
    $registry 	= Zend_Registry::getInstance();
	$auth		= Zend_Auth::getInstance(); 
	$DB = $registry['DB'];
	$authAdapter = new Zend_Auth_Adapter_DbTable($DB);
    $authAdapter->setTableName('users')
    ->setIdentityColumn('username')
    ->setCredentialColumn('password');    
	// Impostare i valori di input delle credenziali
	$uname = $request->getParam('username');
	$paswd = $request->getParam('password');
    $authAdapter->setIdentity($uname);
    $authAdapter->setCredential(md5($paswd));
    // Eseguire la query di autenticazione
    // salvando il risultato
    $result = $auth->authenticate($authAdapter);
    if($result->isValid()){
//print_r($result);
	  $data = $authAdapter->getResultRowObject(null,'password');
	  $auth->getStorage()->write($data);
	  $this->_redirect('/user');
	}else{
	  $this->_redirect('/user/loginform');
	}
  }  
  public function nameAction()
  {
    $request = $this->getRequest();
    $this->view->assign('name', $request->getParam('username'));
    $this->view->assign('gender', $request->getParam('gender'));	  
    $this->view->assign('title', 'Nome Utente');
  }  
  public function registerAction()
  {
    $request = $this->getRequest();
	$this->view->assign('action',"process");
    $this->view->assign('title','Registrazione Membri');
	$this->view->assign('label_fname','Nome');
	$this->view->assign('label_lname','Cognome');
	$this->view->assign('label_uname','Nome Utente');
	$this->view->assign('label_pass','Password');
	$this->view->assign('label_submit','Registra');
	$this->view->assign('description','Compilare questo modulo completamente:');
  }
  public function editAction()
  {
    $registry = Zend_Registry::getInstance();
	$DB = $registry['DB'];
    $request = $this->getRequest();
	$id 	 = $request->getParam("id");
	$sql = "SELECT * FROM `user` WHERE id='".$id."'";
	$result = $DB->fetchRow($sql);
	$this->view->assign('data',$result);
	$this->view->assign('action', $request->getBaseURL()."/user/processedit");
    $this->view->assign('title','Modifica Membri');
	$this->view->assign('label_fname','Nome');
	$this->view->assign('label_lname','Cognome');
	$this->view->assign('label_uname','Nome Utente');
	$this->view->assign('label_pass','Password');
	$this->view->assign('label_submit','Edita');
	$this->view->assign('description','Compilare questo modulo completamente:');
  }  
  public function processAction()
  {
    $registry = Zend_Registry::getInstance();
	$DB = $registry['DB'];
    $request = $this->getRequest();
	$data = array('first_name' => $request->getParam('first_name'),
	  'last_name' => $request->getParam('last_name'),
				  'user_name' => $request->getParam('user_name'),
				  'password' => md5($request->getParam('password'))
	  );
    $DB->insert('user', $data);	
    $this->view->assign('title','Processo di registrazione');
	$this->view->assign('description','Registrazione avventa');  	
  }
  public function listAction()
  {
    $registry = Zend_Registry::getInstance();
	$DB = $registry['DB'];
	$sql = "SELECT * FROM `user` ORDER BY user_name ASC";
	$result = $DB->fetchAssoc($sql);
    $this->view->assign('title','Lista membri');
	$this->view->assign('description','Sotto, nostri membri:');
	$this->view->assign('datas',$result);		
  }
  public function processeditAction()
  {
    $registry = Zend_Registry::getInstance();
	$DB = $registry['DB'];
	$request = $this->getRequest();
	$data = array('first_name' => $request->getParam('first_name'),
	  'last_name' => $request->getParam('last_name'),
				  'user_name' => $request->getParam('user_name'),
				  'password' => md5($request->getParam('password'))
	  );
    $DB->update('user', $data,'id = '.$request->getParam('id'));	
    $this->view->assign('title','Processo di modifica');
	$this->view->assign('description','Modifica eseguita');		
  }
  public function delAction()
  {
    $registry = Zend_Registry::getInstance();
	$DB = $registry['DB'];
	$request = $this->getRequest();
    $DB->delete('user', 'id = '.$request->getParam('id'));	
    $this->view->assign('title','Eliminazione Dati');
	$this->view->assign('description','Eliminazione avvenuta');
    $this->view->assign('list',$request->getBaseURL()."/user/list");  
  }
}
?>
Impossibile utilizzare oggetti di tipo stdClass come array
Se eseguiamo l’esempio precedente e riceviamo il seguente messaggio di errore: C:\AppServ5\www\test\zend\ciaoMondo\library\Zend\Auth\Adapter\DbTable.php on line 340 Se avete lo stesso messaggio di errore, cerchiamo di risolvere questo problema. Saltare questo capitolo se non avete lo stesso errore.
Purtroppo, ancora non ho avuto molto tempo per sapere come risolvere questo errore quando stavo scrivendo questo post. Così, ho deciso di fissarlo al cuore della libreria Zend. Vi dirò dopo se trovo la correzione per questo errore.
Ok, Aprire il file DbTable.php sotto la cartella library\Zend\Auth\Adapter\. Aggiornare la linea 340:
Prima:
Copia codice

if ($resultIdentity['zend_auth_credential_match'] != '1') {
Dopo:
Copia codice

if ($resultIdentity->zend_auth_credential_match != '1') {
Quindi, aggiornare la linea 346:
Copia codice

unset($resultIdentity['zend_auth_credential_match']);
Diventa:
Copia codice

unset($resultIdentity->zend_auth_credential_match);

Nota

Andando a cercare una soluzione semplice senza modificare lo Zend Framework ho trovato una funzione ricorsiva che garantisce il recupero dei dati come ci si aspetta

Copia codice

<?php
function objectToArray($d) {
	if (is_object($d)) {
		// Ottiene le proprietà dell'oggetto
		// data con funzione get_object_vars()
		$d = get_object_vars($d);
	}
	if (is_array($d)) {
		/*
		* Restituisce un'array convertito
		* in oggetto usando
		*  __FUNCTION__ (costante magica)
		* con la chiamata ricorsiva
		*/
		return array_map(__FUNCTION__, $d);
	}
	else {
		// ritorna l'array
		return $d;
	}
}
?>
Questo metodo lo possiamo inserire nel file “UserController.php” sotto la cartella application/controllers e utizzarlo come segue:
Copia codice

<?php
$data = $this->objectToArray($this->data);
?>

Pagina protetta
Abbiamo creato l’autenticazione nel capitolo precedente. Ora, cerchiamo di proteggere una pagina. Così, quando i non membri tentano di entrare nella pagina, verrà reindirizzato alla form di login.
In primo luogo, creiamo la view. Creare un file denominato “userpage.phtml” sotto la cartella application/views/scripts/user. Inserire il seguente codice:
Copia codice

<? include "header.phtml"; ?>
<h1>Ciao, <?=$this->escape($this->username);?></h1>
<a href='<?=$this->escape($this->urllogout);?>'>Logout</a>
<? include "footer.phtml"; ?>
Poi, si aggiunge un metodo al controller.
Aprire il file “UserController.php“. Aggiungere il seguente metodo:

Copia codice

public function userpageAction(){
    $auth		= Zend_Auth::getInstance(); 
	if(!$auth->hasIdentity()){
	  $this->_redirect('/user/loginform');
	}
    $request = $this->getRequest();
	$user		= $auth->getIdentity();
	$real_name	= $user->real_name;
	$username	= $user->username;
	$logoutUrl  = $request->getBaseURL().'/user/logout';
	$this->view->assign('username', $real_name);
	$this->view->assign('urllogout',$logoutUrl);
}
Line 2 – 6 abbiamo bisogno di proteggere gli utenti nella pagina protetta.
Prova a effettuare il login. Puntare il browser su http://localhost/test/zend/ciaoMondo/web_root/user/loginform. Effettuare il login.
Creazione Logout
Nella pagina protetta (nel post precedente, avevamo creato un collegamento al logout. Questo è il discorso del post sulla pagina di logout.
Innanzitutto, creare la view per il logout. Creare un file denominato “logout.phtml” sotto la cartella application/views/scripts/user. Lascia in bianco (perché non vogliamo dimostrare nulla).
Poi, creiamo un metodo per il controller denominato LogoutAction(). Apri il file “UserController.php” sotto la cartella application/controllers. Aggiungere il seguente metodo:
Copia codice

  public function logoutAction()
  {
    $auth = Zend_Auth::getInstance();
	$auth->clearIdentity();
	$this->_redirect('/user');
  }
Ci basta usare clearIdentity(). Poi farà redirect ad un’altra pagina (in questo esempio per l’utente).
Creazione di commutazione per il Front Page
Questo è l’ultimo post di questo capitolo. Noi modificheremo prima pagina (user/index). Quando i visitatori accederanno a questa pagina, saranno reindirizzati al form di login.
Aprire il file “UserController.php” sotto la cartella application/controllers. Aggiornare indexAction():
Copia codice

  public function indexAction()
  {
    $request = $this->getRequest();
    $auth		= Zend_Auth::getInstance();
	if(!$auth->hasIdentity()){
	  $this->_redirect('/user/loginform');
	}else{
$this->_redirect('/user/userpage');
	}
  }
Ok, qui di seguito codice completo per il controller di questa sessione:
Copia codice

<?php
require_once 'Zend/Controller/Action.php';
require_once 'Zend/Auth.php';
require_once 'Zend/Auth/Adapter/DbTable.php';
class UserController extends Zend_Controller_Action
{
  public function indexAction()
  {
    $request = $this->getRequest();
    $auth		= Zend_Auth::getInstance();
	if(!$auth->hasIdentity()){
	  $this->_redirect('/user/loginform');
	}else{
$this->_redirect('/user/userpage');
	}
  }
  public function userpageAction(){
    $auth		= Zend_Auth::getInstance(); 
	if(!$auth->hasIdentity()){
	  $this->_redirect('/user/loginform');
	}
    $request = $this->getRequest();
	$user		= $auth->getIdentity();
	$real_name	= $user->real_name;
	$username	= $user->username;
	$logoutUrl  = $request->getBaseURL().'/user/logout';
	$this->view->assign('real_name', $real_name);
	$this->view->assign('urllogout',$logoutUrl);
  }
  public function loginformAction()
  {
    $request = $this->getRequest();
	$this->view->assign('action', $request->getBaseURL()."/user/auth");
    $this->view->assign('title', 'Login Form');
    $this->view->assign('username', 'Nome Utente');
    $this->view->assign('password', 'Password');	
  }
  public function authAction(){
    $request 	= $this->getRequest();
    $registry 	= Zend_Registry::getInstance();
	$auth		= Zend_Auth::getInstance(); 
	$DB = $registry['DB'];
	$authAdapter = new Zend_Auth_Adapter_DbTable($DB);
    $authAdapter->setTableName('users')
    ->setIdentityColumn('username')
    ->setCredentialColumn('password');    
	// Impostare i valori di input delle credenziali
	$uname = $request->getParam('username');
	$paswd = $request->getParam('password');
    $authAdapter->setIdentity($uname);
    $authAdapter->setCredential(md5($paswd));
    // Eseguire la query di autenticazione
    // salvando il risultato
    $result = $auth->authenticate($authAdapter);
    if($result->isValid()){
//print_r($result);
	  $data = $authAdapter->getResultRowObject(null,'password');
	  $auth->getStorage()->write($data);
	  $this->_redirect('/user');
	}else{
	  $this->_redirect('/user/loginform');
	}
  }
  public function logoutAction()
  {
    $auth = Zend_Auth::getInstance(); 
	if(!$auth->hasIdentity()){
	  $this->_redirect('/user/loginform');
	}
	$auth->clearIdentity();
	$this->_redirect('/user');
  }
  public function nameAction()
  {
    $auth		= Zend_Auth::getInstance(); 
	if(!$auth->hasIdentity()){
	  $this->_redirect('/user/loginform');
	}
    $request = $this->getRequest();
    $this->view->assign('name', $request->getParam('username'));
    $this->view->assign('gender', $request->getParam('gender'));	  
    $this->view->assign('title', 'Nome Utente');
  }  
  public function registerAction()
  {
    $auth		= Zend_Auth::getInstance(); 
	if(!$auth->hasIdentity()){
	  $this->_redirect('/user/loginform');
	}
    $request = $this->getRequest();
	$this->view->assign('action',"process");
    $this->view->assign('title','Registrazione Membri');
	$this->view->assign('label_fname','Nome');
	$this->view->assign('label_lname','Cognome');
	$this->view->assign('label_uname','Nome Utente');
	$this->view->assign('label_pass','Password');
	$this->view->assign('label_submit','Registra');
	$this->view->assign('description','Compilare questo modulo completamente:');
  }
  public function editAction()
  {
    $auth = Zend_Auth::getInstance(); 
	if(!$auth->hasIdentity()){
	  $this->_redirect('/user/loginform');
	}  
    $registry = Zend_Registry::getInstance();
	$DB = $registry['DB'];
    $request = $this->getRequest();
	$id 	 = $request->getParam("id");
	$sql = "SELECT * FROM `user` WHERE id='".$id."'";
	$result = $DB->fetchRow($sql);
	$this->view->assign('data',$result);
	$this->view->assign('action', $request->getBaseURL()."/user/processedit");
    $this->view->assign('title','Modifica Membri');
	$this->view->assign('label_fname','Nome');
	$this->view->assign('label_lname','Cognome');
	$this->view->assign('label_uname','Nome Utente');
	$this->view->assign('label_pass','Password');
	$this->view->assign('label_submit','Edita');
	$this->view->assign('description','Compilare questo modulo completamente:');
  }  
  public function processAction()
  {
    $auth		= Zend_Auth::getInstance(); 
	if(!$auth->hasIdentity()){
	  $this->_redirect('/user/loginform');
	}
    $registry = Zend_Registry::getInstance();
	$DB = $registry['DB'];
    $request = $this->getRequest();
	$data = array('first_name' => $request->getParam('first_name'),
	  'last_name' => $request->getParam('last_name'),
				  'user_name' => $request->getParam('user_name'),
				  'password' => md5($request->getParam('password'))
	  );
    $DB->insert('user', $data);
    $this->view->assign('title','Processo di registrazione');
	$this->view->assign('description','Registrazione avventa');
  }
  public function listAction()
  {
    $auth		= Zend_Auth::getInstance(); 
	if(!$auth->hasIdentity()){
	  $this->_redirect('/user/loginform');
	}
    $registry = Zend_Registry::getInstance();
	$DB = $registry['DB'];
	$sql = "SELECT * FROM `user` ORDER BY user_name ASC";
	$result = $DB->fetchAssoc($sql);
    $this->view->assign('title','Lista membri');
	$this->view->assign('description','Sotto, nostri membri:');
	$this->view->assign('datas',$result);		
  }
  public function processeditAction()
  {
    $auth		= Zend_Auth::getInstance(); 
	if(!$auth->hasIdentity()){
	  $this->_redirect('/user/loginform');
	}
    $registry = Zend_Registry::getInstance();
	$DB = $registry['DB'];
	$request = $this->getRequest();
	$data = array('first_name' => $request->getParam('first_name'),
	  'last_name' => $request->getParam('last_name'),
				  'user_name' => $request->getParam('user_name'),
				  'password' => md5($request->getParam('password'))
	  );
    $DB->update('user', $data,'id = '.$request->getParam('id'));	
    $this->view->assign('title','Processo di modifica');
	$this->view->assign('description','Modifica eseguita');
  }
  public function delAction()
  {
    $auth		= Zend_Auth::getInstance(); 
	if(!$auth->hasIdentity()){
	  $this->_redirect('/user/loginform');
	}
    $registry = Zend_Registry::getInstance();
	$DB = $registry['DB'];
	$request = $this->getRequest();
    $DB->delete('user', 'id = '.$request->getParam('id'));	
    $this->view->assign('title','Eliminazione Dati');
	$this->view->assign('description','Eliminazione avvenuta');
    $this->view->assign('list',$request->getBaseURL()."/user/list");  
  }
}
?>