- Sat
- 13
- Sep
- 08
Costruire un’applicazione reale con Zend Framework ( parte 8 )
Di in Php, Zend Framework Controls: +-close
Autenticazione
L’autenticazione è il processo in cui bisogna capire se qualcuno è realmente chi dice di essere. Per identificare l’individuo, solitamente si usa l’accoppiata username e password. Altri metodi di autenticazione sono esistenti, ad esempio, quando si paga in un negozio con la carta di credito, l’username è sostituito dal possesso materiale della carta di credito, altri metodi potrebbero essere la lettura delle impronte digitali ecc..
In Zend Framework il processo di autenticazione è gestito da un oggetto, Zend_Auth. In questo articolo, procederemo a creare un nuovo controller, AuthController e la sua rispettiva view, che visualizzerà il form per l’inserimento di username e password ed eventualmente dei messaggi di errore.
AuthController.php
< ?php
class AuthController extends Zend_Controller_Action
{
public function init(){
$response = $this->getResponse();
$response->insert('header', $this->view->render('header.phtml'));
$response->insert('menu', $this->view->render('menu.phtml'));
$response->insert('columnLeft', $this->view->render('columnLeft.phtml'));
$response->insert('columnRight', $this->view->render('columnRight.phtml'));
$response->insert('footer', $this->view->render('footer.phtml'));
}
public function indexAction() {
$this->_forward('login');
}
public function loginAction() {
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$this->_redirect('/');
}
$flashMessenger = $this->_helper->FlashMessenger;
$flashMessenger->setNamespace('actionErrors');
$this->view->actionErrors = $flashMessenger->getMessages();
}
public function identifyAction(){
$success = false;
$message = '';
if ($this->_request->isPost()){
$formData = $this->_getFormData();
if (empty($formData['username']) || empty($formData['password'])){
$message = 'Please provide a username and password.';
}else{
$authAdapter = $this->_getAuthAdapter($formData);
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($authAdapter);
if($result->isValid()) {
$data = $authAdapter->getResultRowObject(null,'password');
$auth->getStorage()->write($data);
$success = true;
$redirectUrl = $this->_redirectUrl;
}else{
$message = 'Login failed';
}
}
}
if(!$success){
$flashMessenger = $this->_helper->FlashMessenger;
$flashMessenger->setNamespace('actionErrors');
$flashMessenger->addMessage($message);
$redirectUrl = '/auth/login';
}
$this->_redirect($redirectUrl);
}
protected function _getAuthAdapter($formData){
$dbAdapter = Zend_Registry::get('db');
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter->setTableName('utenti')
->setIdentityColumn('username')
->setCredentialColumn('password');
$config = Zend_Registry::get('config');
$salt = $config->auth->salt;
$password = sha1($salt.$formData['password']);
$authAdapter->setIdentity($formData['username']);
$authAdapter->setCredential($password);
return $authAdapter;
}
protected function _getFormData(){
$data = array();
$filterChain = new Zend_Filter;
$filterChain->addFilter(new Zend_Filter_StripTags);
$filterChain->addFilter(new Zend_Filter_StringTrim);
$data['username'] = $filterChain->filter($this->_request->getPost('username'));
$data['password'] = $filterChain->filter($this->_request->getPost('password'));
return $data;
}
public function logoutAction() {
$auth = Zend_Auth::getInstance();
$auth->clearIdentity();
$this->_redirect('/');
}
}
Come per l’IndexController anche questo AuthController contiene il metodo init() utile all’inserimento nell’output delle parti comuni del layout (header, footer ecc.. ).
L’indexAction altro non contiene che una redirezione alla loginAction, in modo tale che entrando nella pagina di autorizzazione senza specificare una action, login venga eseguita. La LoginAction redireziona l’output nell’IndexController ( quindi nella homepage ) del sito nel caso in cui l’utente sia già autorizzato, ovvero nel caso in cui $auth->hasIdentity() ritorni true. Inoltre viene recuperato l’helper FlashMessenger, che contiene eventuali messaggi salvati da una precedente azione, salvati nella proprietà $this->view->actionErrors, in modo tale da poterli visualizzare nella vista.
Alla loginAction è legata la view login.phtml, il seguente è il codice:
login.phtml
<h1>Log in</h1>
<p>Please log in here</p>
<?php echo isset($this->actionErrors[0]) && !empty($this->actionErrors[0]) ? "<p class='error'>" . $this->escape($this->actionErrors[0]) . "</p>" : ""; ?>
<form method="POST"
action="<?php echo $this->LinkTo('auth/identify'); ?>">
<div>
<label>Username</label>
<input type="text" name="username" value="" />
</div>
<div>
<label>Password</label>
<input type="password" name="password" value="" />
</div>
<div>
<input type="submit" name="login" value="Login" />
</div>
</form>
L’unico particolare degno di nota di questo file è l’attributo action del form. Questo è generato da un view helper, LinkTo che si occupa di creare la corretta url per la identifyAction, recuperando il valore corretto di $baseUrl.
LinkTo.php
< ?php
class Zend_View_Helper_LinkTo
{
protected static $baseUrl = null;
public function linkTo($path){
if(self::$baseUrl === null){
$request = Zend_Controller_Front::getInstance()->getRequest();
$root = '/' . trim($request->getBaseUrl(), '/');
if ($root == '/'){
$root = '';
}
self::$baseUrl = $root . '/';
}
return self::$baseUrl . ltrim($path, '/');
}
}
Procedendo con le action dell’AuthController troviamo l’identifyAction, che controlla l’esistenza di una richiesta POST, quindi filtra il contenuto dell’array POST passandolo al metodo _getFormData
, che filtra il suo contenuto utilizzando l’oggetto Zend_Filter e aggiungendo come filtri gli oggetti Zend_Filter_StripTags e Zend_Filter_StringTrim, il cui compito è il medesimo delle funzioni built in del linguaggio trim() e strip_tags.
I dati inviati vengono quindi passati al metodo _getAuthAdapter che si occupa di istanziare la classe Zend_Auth_Adapter_DbTable a quale passeremo l’oggetto $db recuperato dal registro ed indicheremo la tabella e i campi in cui dovranno essere verificati l’username e la password inviate. Per rendere il tutto più sicuro la password, oltre ad essere salvata criptata sul database tramite l’algoritmo SHA1, è unita ad un salt, una stringa casuale salvata nel nostro file di configurazione, il che rende estremamente difficile, se non impossibile, recuperare il valore della password conoscendo il suo valore criptato e cercando di effettuare un reverse engineering.
L’oggetto Zend_Auth_Adapter_DbTable ritornato dal nostro metodo _getAuthAdapter sarà quindi passato a Zend_Auth, che ci confermerà o meno l’esistenza dell’utente tramite la chiamata del metodo sValid(). In caso di fallimento l’output sarà redirezionato alla medesima pagina di autenticazione accompagnata dal messaggio indicante la non riuscita dell’operazione. In caso di successo, i dati utente recuperati saranno salvati nella sessione, fatta eccezione che per la password.
Messaggio di benvenuto
In ogni sito che si rispetti, una volta autenticati il sistema ci da un messaggio di benvenuto, indicante il nostro nome. Ebbene, anche il nostro sistema godrà di questa caratteristica, utilizzando un nuovo view helper, LoggedInUser.
LoggedInUser
< ?php
class Zend_View_Helper_LoggedInUser {
protected $_view;
function setView($view) {
$this->_view = $view;
}
function loggedInUser(){
$auth = Zend_Auth::getInstance();
if($auth->hasIdentity()){
$logoutUrl = $this->_view->linkTo('auth/logout');
$user = $auth->getIdentity();
$username = $this->_view->escape(ucfirst($user->username));
$string = 'Loggato come ' . $username . ' | Log out';
}else{
$loginUrl = $this->_view->linkTo('auth/login');
$string = 'Log in';
}
return $string;
}
}
La stringa ritornata sarà visualizzata, per esempio, nell’header.
header.phtml
< ?php echo $this->LoggedInUser();?>Paesidelmondo Header
Con questo si conclude il tutorial all’autenticazione con Zend Framework. I commenti, aggiunte, correzioni o altro sono sempre graditi.
Related posts:
- Zend Framework: introduzione al componente Zend_Form Creare form web con Zend Form Con Zend Framework possiamo...
- Zend Framework: gestione dei moduli ed esempio modulo di amministrazione Come usare Zend_Layout per la gestione dei moduli In quest'articolo...
Related posts brought to you by Yet Another Related Posts Plugin.












Ciao, come faccio per impostare un cookie, in modo che quando rivado sul sito non devo rifare il login??’
Ciao, purtroppo attualmente non so come fare quello che chiedi, ma mi ci metterò al lavoro subito e scriverò qualcosa a proposito.
Grazie mille e complimenti per il sito, tratta delle tematiche molto interessanti, l’ unico che tratta lo zend framework in modo intuitivo.
Ciao,
scusa ma non riesco a far funzionare la tua applicazione perchè mi dice che
non trova la pagina
identify
che per quento ho capito essendo alle prime armi è un metodo del controller
Grazie mille
Andrea
Dovresti postare l’errore come ti viene restituito in modo da avere maggiori elementi per aiutarti.
Ciao
Stesso problema!!!
Ciao Carlo,
se posti l’errore che ottieni, sarò felice di aiutarti.
Ciao
Razorblade´s last blog ..Neobazaar annunci gratuiti: esempio di una applicazione sviluppata con Zend Framework
Ciao.
nessun messaggio di errore.
mi reindirizza su questa pagina “http://www.myproject/admin/identify” completamente bianca.
Che sara ?
Vuol dire che in quella action c’è un errore e l’applicazione esce. Non vedi nessun messaggio di errore perchè non sono abilitati. Per abilitarli setta questi valori nel file di configurazione
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
ed inoltre aggiungi
error_reporting(E_ALL | E_STRICT);
come prima linea del tuo file index.php pubblico.
A questo punto, riaggiornando la pagina dovresti essere in grado di visualizzare il messaggio di errore, postalo.
Ciao
mmm prima perfavore aiutami a capire una cosa.
Io gestisco il pannell di controllo come modulo
modules/
admin/
controlles/
IndexController.php (dove viene precaricato il layout e il menu del pannello di controllo)
Posso aggiungere il controller AuthController e gestire le autorizzazioni e ruoli da qui per poi precaricare l’index del IndexController ??
o devo gestire il tutto solo con un Controller ???
Sono stato chiaro ??
grazie
Ehm… non so se ho capito, provo a risponderti. L’Auth_Controller puoi averlo anche in admin, non c’è problema, non ho ben capito quello che hai detto dopo, ma dopo aver fatto loggare l’utente puoi redirezionarlo dove ti pare.
Ciao
Ciao,
ho ripreso il tuo tutorial.
Continua a darmi sempre una pagina bianca e non riesco a leggere nessuna riga di errore, anche se setto a 1 i pametri php.
Che faccio ?
Grazie
Sei proprio sicuro di aver anche messo
error_reporting(E_ALL | E_STRICT);
come prima linea dell’index pubblico?
Se continua a piantarsi senza dare nessun genere di output è perchè la visualizzazione degli errori è stata disabilitata lato server.
Stai provando in locale o su un hosting?