Zend_Auth: Identificación y autentificación en Zend Framework

Zend FrameworkÚltimamente en el trabajo estoy aprendiendo Zend Framework, y he tenido que estudiar el componente Zend_Auth de la librería. En pocas palabras, se encarga de la autentificación, es decir, la parte de identificar al usuario. Hay que marcar que la autenticación no es lo mismo que la autorización, que se encarga de los privilegios y permisos (de esto miraré de hablar en otra entrada, sobre Zend_Acl).

Primero, necesito explicar que estamos creando un plugin que se encarga de comprobar cada petición, que el usuario este autentificado. Como plugin, estará en la carpeta application/plugin. Se llamará CheckAccess, extiende la clase Zend_Controller_Plugin_Abstract, y la he convertido en una clase singleton, para utilizarla desde los controladores sin necesidad de volverla a instanciar.

El principio de la clase sería algo así:

<?php
class Plugin_CheckAccess extends Zend_Controller_Plugin_Abstract
{
    /**
     * Contiene el objeto Zend_Auth
     *
     * @var Zend_Auth
     */
    private $_auth;
 
    /**
     * El objeto de la clase singleton
     *
     * @var Plugin_CheckAccess
     */
    static private $instance = NULL;
 
    /**
     * Constructor
     */
    private function __construct()
    {
        $this->_auth =  Zend_Auth::getInstance();
    }
 
    /**
     * Devuelve el objeto de la clase singleton
     *
     * @return Plugin_CheckAccess
     */
    static public function getInstance() {
       if (self::$instance == NULL) {
          self::$instance = new Plugin_CheckAccess ();
       }
       return self::$instance;
    }
 
    ...

En este plugin, solo nos falta comprobar que este autentificado antes de llegar la petición al controlador. Para ello, le preguntaremos a Zend_Auth si ya se ha identificado el usuario. En caso negativo, y si la petición no este pidiendo el formulario de login, lo redirigiremos hacia allí.

    ...
 
    /**
     * preDispatch
     *
     * Funcion que se ejecuta antes de que lo haga el FrontController
     *
     * @param Zend_Controller_Request_Abstract $request Peticion HTTP realizada
     * @return
     * @uses Zend_Auth
     *
     */
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $controllerName = $request->getControllerName();
 
        // Si el usuario esta autentificado
        if ($this->_auth->hasIdentity()) {
 
        } else {
            // Si el Usuario no esta identificado y no se dirige a la página de Login
            if ($controllerName != 'login') {
                // Mostramos al usuario el Formulario de Login
                $request->setControllerName("login");
                $request->setActionName("index");
            }
        }
    }
}

Ahora solo hace falta la parte en que te identificas como usuario en la aplicación, y la parte de cuando sales y quieres cerrar la sesión abierta. Esta parte iría dentro del controlador, que según la acción, hará una cosa o otra.

En la acción que se encarga de comprobar que los datos que llegan del formulario sean correctos y la identificación sea válida, es donde necesitamos utilizar Zend_Auth para que realize él la validación, y en caso afirmativo, almacene la identidad del usuario. Crearemos un adaptador de Zend_Auth,  para que realize la comprobación contra una tabla de la base de datos. Solo hay que indicarle la tabla y dos de sus campos: el que identifica y el de la contraseña. Después le pasamos los valores del formulario de identificación, y Zend_Auth realiza las comprobaciones pertinentes.

    /**
     * Comprobar Login
     *
     * Accion que comprueba los datos del usuario
     *
     * @param  Zend_Form
     * @return  Zend_Form
     * @uses    Form_Login    Para recuperar los datos que el usuario ha enviado
     */
    public function comprobar($form)
    {
    	// Comprobamos si el Formulario pasa la Validacion
        if ($form->isValid($_POST)) {
            // Recuperamos los valores
            $values = $form->getValues();
 
            // Creamos un adaptador de Zend_Auth para consultar una tabla de la base de datos
            $authAdapter = new Zend_Auth_Adapter_DbTable(Zend_Db_Table::getDefaultAdapter());
            $authAdapter ->setTableName('usuarios')              // Nombre de la tabla
                         ->setIdentityColumn('name')             // Campo de identificación
                         ->setCredentialColumn('password')       // Campo de contraseña
                         ->setIdentity($values['name'])          // Valor de identificación
                         ->setCredential($values['password']);   // Valor de contraseña
 
            // Recogemos Zend_Auth
            $auth = Zend_Auth::getInstance();
            // Realiza la comprobación con el adaptador que hemos creado
            $result = $auth->authenticate($authAdapter);
 
            // Si la autentificación es válida
            if ($result->isValid()) {
                // Recoge los valores de las columnas del registro de la Base de Datos y
                // los almacena como identidad en Zend_Auth, para un uso posterior
                $data = $authAdapter->getResultRowObject(array('name','email','rol'));
                $auth->getStorage()->write($data);
 
                $this->_redirect('/');
 
            } else {
                $this->view->loginError = $result->getMessages();
            }
        }
        return $form;
    }

Lo último que hace falta es el código para cuando el usuario cierra la sesión. Se trata de decirle a Zend_Auth que elimine toda la información que contiene y cierre sesión.

	/**
	 * Cerrar sesión
	 *
	 * Elimina los datos almacenados en el Zend_Auth
	 */
	public function logoutAction()
	{
            Zend_Auth::getInstance()->clearIdentity();
            $this->_redirect('/');
	}

7 comentarios en “Zend_Auth: Identificación y autentificación en Zend Framework

  1. Me ayudo bastante este post, muchas gracias.
    Ojala postees mas de Zend Framework, que lo estoy aprendiendo y no es tan facil.

  2. Muchas gracias… y sería muy bueno que escribieras un tutorial completo integrando el Zend Auth, Acl y lo demás que corresponda a un login de usuarios. Gracias nuevamente!

  3. Hola

    ¿Y como lo registro? Yo sólo quiero que me haga la autenticación en un Action concreto, así que pongo lo siguiente:

    public function nuevoAction() {
    Zend_Controller_Front::getInstance()->registerPlugin(Application_Plugin_CheckAccess::getInstance());
    }

    Pero no hacen nada… en cambio si escribo la línea anterior dos veces entonces sí que funciona. ¿Qué hago mal?

    Saludos y gracias!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>