December 29th, 2011 Category: Curso Zend Framework
42 Comments »
En los anteriores capitulos habiamos usado el video como metodo de aprendizaje, hoy habiendo cubierto la parte inicial y basica de Zend Framework, creo que estamos preparados para dejar el video atras, y continuar los capitulos leyendo un poco.
En este capitulo vamos a ver como crear un sistema de login en nuestro proyecto. Nosotros actualmente en nuestro portal de noticias tenemos una pantalla donde publicamos nuestras noticias. Pero actualmente esa pantalla es accesible por cualquier persona.
El objetivo de este capitulo es crear una pantalla de login, y restringir el acceso a la administracion de las noticias solo a las personas que tengan usuario y contraseña.
Lo primero que vamos a hacer es crear un nuevo controller, UsuarioController.php
El codigo de este controller inicialmente sera asi.
class UsuarioController extends Zend_Controller_Action
{
public function init()
{
}
public function loginAction()
{
$form = new Application_Form_Login();
if( $this->getRequest()->isPost() ){
if( $form->isValid( $this->_getAllParams() )) {
// Do something
}
}
$this->view->form = $form;
}
}
Para este controller vamos a tener que crear una vista asi que creamos la carpeta en views/scripts/usuario y agregamos el archivo login.phtml, donde vamos a imprimir el formulario y mostrar un mensaje, el archivo quedaria asi
<div>
<h2>Ingresar al sistema</h2>
<?php echo $this->form ; ?>
</div>
Tambien vamos a necesitar un formulario para poder ingresar usuario y contraseña.
Creamos el archivo en forms/Login.php
Este formulario va a tener un input para el usuario otro para el contraseña, y el boton de submit, el formulario Login.php nos quedaria asi.
class Application_Form_Login extends Zend_Form
{
public function init()
{
$this->addElement(
'text', 'username', array(
'label' => 'Usuario:',
'required' => true
)
);
$this->addElement(
'password', 'password', array(
'label' => 'Contraseña:',
'required' => true
)
);
$this->addElement(
'submit', 'Ingresar', array()
);
}
}
Hasta ahora no vimos nada nuevo, es mas o menos el mismo mecanismo que usamos para crear un nuevo post. Si entramos en la url de nuestro proyecto /usuario/login vamos a ver el formulario de login como aparece en la siguiente imagen.

Ahora que tenemos el codigo vamos a crear una tabla donde se van a guardar todos los usuarios que van a tener permisos al panel de administracion de nuestro proyecto. El sql para crear la tabla es el siguiente.
CREATE TABLE IF NOT EXISTS `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(40) NOT NULL,
`password` char(40) NOT NULL,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
);
INSERT INTO `users` (`username`, `password`) VALUES
('pablo', '7c4a8d09ca3762af61e59520943dc26494f8941b');
Nuestra tabla de usuario es bastante sencilla, por ahora vamos a cumplir con los requerimientos minimos. El hash extraño que se ve es la contraseña “123456″ encriptada con la funcion sha1()
Ahora que ya tenemos un usuario (pablo) y una contraseña (123456), nos falta agregar la logica para que se valide si el usuario existe o no.
Zend Framework nos brinda el componente Zend_Auth el cual a partir de sus Adapters, nos permite validar un usuario y loguearlo en el sistema. La forma de usarlo es bastante simple, Zend Auth entiende identidad y credencial, donde la identidad es el nombre de usuario o mail que vamos a usar para identificar a un usuario dentro del sistema, y la credencia es la contraseña.
Nosotros vamos a usar Zend_Db_Adapter_DbTable el cual se encarga de validar el usuario y contraseña en nuestra base de datos.
El codigo cuando usemos Zend_Auth deberia ser el siguiente.
$authAdapter = new Zend_Auth_Adapter_DbTable();
$authAdapter
->setTableName('users')
->setIdentityColumn('username')
->setCredentialColumn('password');
$authAdapter
->setIdentity('pablo')
->setCredential(sha1('123456'));
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($authAdapter);
if( $result->isValid() ){
echo "Estamos Logueado!";
}else{
echo "Datos incorrecto";
}
Ahora este codigo vamos a adaptarlo a nuestro controller. Nos quedaria asi
class UsuarioController extends Zend_Controller_Action
{
public function init()
{
}
public function loginAction()
{
$form = new Application_Form_Login();
if( $this->getRequest()->isPost() ){
if( $form->isValid( $this->_getAllParams() )) {
$authAdapter = new Zend_Auth_Adapter_DbTable();
$authAdapter
->setTableName('users')
->setIdentityColumn('username')
->setCredentialColumn('password');
$authAdapter
->setIdentity($form->getValue('username'))
->setCredential(sha1($form->getValue('password')));
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($authAdapter);
if( $result->isValid() ){
return $this->_redirect('/posts/listar');
}else{
$form->username->addErrorMessage('Datos Incorrectos');
}
}
}
$this->view->form = $form;
}
}
Con este codigo cada vez que nos identifiquemos correctamente nos va a redirigir a /posts/listar donde vamos a mostrar todas las noticias.
Ahora los que nos faltaria agregar es que en cada lugar donde nosotros queramos restringir el acceso, agregar el chequeo si el usuario esta logueado o no, sino esta logueado vamos a redireccionarlo a la pantalla de login.
En cada action que querramos validar esto vamos a agregar el siguiente codigo.
$auth = Zend_Auth::getInstance();
if (! $auth->hasIdentity()) {
return $this->_redirect('/usuarios/login');
}
Notese que en el caso de PostsController, tenemos metodos que son de acceso publico y acceso privado, si llegado el caso tenemos un Controller donde necesitamos que todos los metodos sean de alcance privado, las lineas de arriba podemos escribirlas en el metodo init() de nuestro controller, ese metodo init se va a llamar antes de ejecutar un action de ese controller, y de esta forma evitamos repetir codigo.
Hay otras practicas para mejorar esto pero eso podemos verlo mas adelante.
Ahora que restringimos el acceso, vamos a necesitar la posiblidad de desloguearnos del sistema, para eso vamos agregar un link en nuestro layout.phtml en la parte del menu, que nos redireccione a /usuarios/logout y este es el codigo de nuestro action para desloguarnos.
public function logoutAction()
{
Zend_Auth::getInstance()->clearIdentity();
return $this->_redirect('/usuario/login');
}
Bastante simple, no
, asi es todo con Zend Framework.
Ahora, vamos a dejarlo mas bonito a todo esto, y vamos validar en la vista si el usuario esta logueado, voy a mostrar un link a logout, si esta deslogueado voy a mostrar un link a la pantalla de login. El codigo a agregar en nuestro layout seria el siguiente.
<?php
$auth = Zend_Auth::getInstance();
if ( $auth->hasIdentity()) :
?>
<li>Usuario:<?php echo $auth->getIdentity() ?></li>
<li><a href="/usuario/logout">Logout</a>
<?php else: ?>
<li><a href="/usuario/login/">Login</a>
<?php endif;?>
Y con esto ya somos capaces de agregar un sistema de login en nuestros proyectos usando Zend Framework.
February 4th, 2009 Category: Zend Framework
4 Comments »
En los casos comunes de autenticaciones con Zend_Auth nosotros le pasamos un usuario y una clave, pero hay veces que necesitamos que valide por mas datos.
Una autenticacion comun seria la siguiente.
Zend_Loader::loadClass( 'Zend_Auth_Adapter_DbTable' );
$dbAdapter = Zend_Registry::get( 'dbAdapter' );
$authAdapter = new Zend_Auth_Adapter_DbTable( $dbAdapter );
$authAdapter->setTableName( 'SYS_USER' );
$authAdapter->setIdentityColumn( 'username' );
$authAdapter->setCredentialColumn( 'password' );
$authAdapter->setIdentity( strtolower( trim( $username )) );
$authAdapter->setCredential( md5( $passwd ));
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate( $authAdapter );
Pero que pasa si ademas necesitamos validar si el usuario esta o no activo en el sistema, o si no esta suspendido temporalmente?
Nososotros podemos pasarle un parametro extra a Zend_Auth_Adapter_DbTable, para que filtre por mas datos.
Por ejemplo el caso anterior, quedaria de la siguiente manera si ademas nosotros queremos saber si el campo status = ‘A’
Zend_Loader::loadClass( 'Zend_Auth_Adapter_DbTable' );
$dbAdapter = Zend_Registry::get( 'dbAdapter' );
$authAdapter = new Zend_Auth_Adapter_DbTable( $dbAdapter, 'SYS_USER', 'username', 'password', "MD5( ? ) AND status = 'A' " );
$authAdapter->setIdentity( strtolower( trim( $username )) );
$authAdapter->setCredential( md5( $passwd ));
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate( $authAdapter );
De esta forma, cada vez que intentemos loguearnos nos va a encriptar la clave con la funcion MD5, y preguntar si status =’A’.
Si ustedes no necesitan encriptar la clave pueden usar directamente el signo de pregunta sin la funcion MD5, tambien pueden agregar mas funcionalidades, para mas detalle mirar la documentacion oficial
En el administrador del blogzf tenemos un ejemplo de implementacion de este sistema.
December 17th, 2008 Category: blogzf Zend Framework
40 Comments »
Zend Form
Hoy vamos a ver como armar los formularios. Para eso vamos a usar la carpeta forms dentro de nuestras vistas, ahí vamos a crear una clase para cada formulario.
Muchas ponen los formularios en el controller y algún que otro loco en el modelo, y también en los helpers, nosotros vamos a crear una clase para que resuelva nuestro problema en la carpeta forms de la vista del modulo correspondiente.
Nuestra clase va a tener un solo método init() y va a extender de Zend_Form.
El ejemplo a continuación es el de login de usuarios, con 3 elementos, usuario, password, y el botón de submit.
setName('authentication');
/**
* Creamos un elemento de tipo Text
* - Seteamos el texto que queremos que represente a este campo
* - Agregamos un filtro, que hace que cuando enviamos el
* fomrulario ponga todo el valor del campo en minuscula
* - Tambien especificamos que el campo es obligatorio.
* - Y agregamos el validador para preguntar si el campo es un campo valido
*/
$username = new Zend_Form_Element_Text('username');
$username->setLabel('Email')
->addFilter('StringToLower')
->setRequired(true)
->addValidator('NotEmpty', true);
/**
* Creamos el elemento tipo password.
* Aca vamos a generar el campo para la clave
*/
$password = new Zend_Form_Element_Password('password');
$password->setLabel('Clave')
->setRequired(true)
->addValidator('NotEmpty', true);
/**
* El boton para enviar el formulario
*/
$submit = new Zend_Form_Element_Submit('submit');
$submit->setLabel('Entrar');
/**
* Agregamos los elementos al formulario
*/
$this->addElements(array($username , $password , $submit));
}
}
Como se habrán dado cuenta nuestro archivo se va a llamar Authentication.php
Cada vez que se instancie y se imprima este objeto nos va a dibujar automaticamente nuestro formulario.
Ahora vamos a llamar a mostrar el formulario en nuestras paginas.
Vamos al controller
_request->isPost()) {
$credentials = $this->_request->getPost();
if ($form->isValid($credentials)) {
$authAdapter = new Zend_Auth_Adapter_DbTable(
Zend_Db_Table::getDefaultAdapter(),
'users','username','password', 'MD5(?) AND status="ENABLED"');
// Set the input credential values to authenticate against
$authAdapter->setIdentity($credentials['username']);
$authAdapter->setCredential($credentials['password']);
$result = Zend_Auth::getInstance()->authenticate( $authAdapter );
if ($result->isValid()) {
$this->_redirect('/admin/dashboard/');
}
$this->_flashMessenger->addError('usuario incorrecto');
$form->populate($credentials);
} else {
$this->_flashMessenger->addError('Hay datos invalidos o vacios');
$form->populate($credentials);
}
}
$this->view->form = $form;
}
}
En nuestro indexAction vemos que lo primero que se hace es instanciar la clase forms_Authentication que creamos anteriormente. Seguidamente tenemos una linea que pregunta si hay datos enviados via post, en nuestro caso esta condicion va a ser falsa porque todavia no enviamos ningun formulario. Asi que vamos a explicar lo que hacemos en caso de que no se haya enviado el formulario aun.
$this->view->form = $form;
Aca estamos pasando a la vista nuestro objeto Form. Para dibujar nuestro formulario desde el controller esto es lo unico que tenemos que hacer.
Ahora pasemos a la vista. Y veamos como queda de complejo nuestro index/index.phtml
=$this->form?>
Esto solo y nos deberia mostrar lo siguiente.
Ahora que ya tenemos nuestro formulario vamos a completar datos y enviarlo. Completamos con cualquier dato. Pero para probar vamos a completar el usuario y no la clave. Para aprender a usar los Validators.
Si hacemos esto nos deberia aparecer el formulario resaltando el problema por el cual no proceso el formulario.
Y como hicimos esto?
Muy facil, cuando creamos el formulario, no especificamos a donde queremos que envie los datos, entonces los envia a si mismo.
Esto quiere decir que enviamos un post a indexAction, ahora el condicional if ($this->_request->isPost()) nos va a dar verdadero.
Lo siguiente que preguntamos es si los datos de nuestro formulario son validos, en el caso que lo sean vamos a seguir con el logueo de usuario. En caso contrario vamos a volver a mostrar el formulario con los datos que envio el usuario, y agregano los errores correspondientes, esto lo hacemos llamando al metodo populate de Zend_Form, que solo se encarga de completar los datos que vinieron por post en el elemento correspondiente, y los errores. Lamentablemente los errores estan en ingles, y por ahora vamos a dejarlo asi. Tambien agregamos un error con el flashHelper de Zsamer.
Ahora probemos completar todos los datos, si corresponden a los de la base de datos te va a loguear, y redireccionar a tu dashboard.
Zend Auth.
Una de las cosas que mas me sorprendio cuando empeze con Zend Framework, fue la cantidad de tutoriales sobre este componente. La verdad que no tiene mucha mistica, pero el uso que le damos en blogzf es bastante basico y comun,
Primero instanciamos la clase Zend_Auth_Adapter_DbTable, y le pasamos los datos de nuestra tabla donde guardamos los datos de los usuarios, seteamos la columna donde esta el identificador, y la columna donde esta la clave (credencial).
Ya con la instancia seteamos los datos que vinieron con el formulario.
Y si Zend_Auth::getInstance()->authenticate( $authAdapter )->isValid() nos da true, estamos logueados.
Facil?, si es Zend.
Ahora necesitamos preguntar en cada modulo que lo requiera si el usuario ya esta logueado, en caso que no lo este vamos a redireccionarlo a la pantalla de login. En nuestro sistema lo vamos a hacer desde el plugin de Blogzf_Controller_Plugin_Backoffice.
$auth = Zend_Auth::getInstance();
if ( $request->module == 'admin' ) {
if( !$auth->hasIdentity() && $request->controller != 'index' ) {
header('Location: /admin/');
} elseif ( $auth->hasIdentity() && $request->controller == 'index' ) {
header('Location: /admin/dashboard/');
}
}
Con esto es suficiente.




