Autenticación en Zend Framework 2

El componente de autenticación en Zend Framework 2 nos sirve para identificarnos en la aplicación.
A continuación haremos un login de usuarios.

El controlador:

<?php
namespace Modulo\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Validator;
use Zend\I18n\Validator as I18nValidator;
use Zend\Db\Adapter\Adapter;
use Zend\Crypt\Password\Bcrypt;
use Zend\Authentication\Adapter\DbTable as AuthAdapter;

//Componentes de autenticación
use Zend\Authentication\AuthenticationService;
use Zend\Authentication\Storage\Session as SessionStorage;
use Zend\Session\Container;

//Incluir modelos
use Modulo\Model\Entity\UsuariosModel;

//Incluir formularios
use Modulo\Form\LoginForm;

class UsuariosController extends AbstractActionController{
    private $dbAdapter;
    private $auth;
    
	public function __construct() {
		//Cargamos el servicio de autenticación en el constructor
        $this->auth = new AuthenticationService();
    }
	
    public function indexAction(){
	//Vamos a utilizar otros métodos
        return new ViewModel();
    }
    
     public function loginAction(){
	 //
         $auth = $this->auth;
         $identi=$auth->getStorage()->read();
         if($identi!=false && $identi!=null){
            return $this->redirect()->toUrl($this->getRequest()->getBaseUrl().'/usuarios/dentro');
         }
        
		//DbAdapter
        $this->dbAdapter=$this->getServiceLocator()->get('Zend\Db\Adapter');
        
		//Creamos el formulario de login
		$form=new LoginForm("form");
        
		//Si nos llegan datos por post
		if($this->getRequest()->isPost()){
		
			/* Creamos la autenticación a la que le pasamos:
				1. La conexión a la base de datos
				2. La tabla de la base de datos
				3. El campo de la bd que hará de username
				4. El campo de la bd que hará de contraseña
			*/
            $authAdapter = new AuthAdapter($this->dbAdapter,
                                           'usuarios',
                                           'email',
                                           'password'
                                           );
										   
		   /*  
			Podemos hacer lo mismo de esta manera:
			$authAdapter = new AuthAdapter($dbAdapter);
			$authAdapter
                ->setTableName('users')
                ->setIdentityColumn('username')
                ->setCredentialColumn('password');
		   */

		   /*
		   En el caso de que la contraseña en la db este cifrada
		   tenemos que utilizar el mismo algoritmo de cifrado
		   */
            $bcrypt = new Bcrypt(array(
                                'salt' => 'aleatorio_salt_pruebas_victor',
                                'cost' => 5));
           
            $securePass = $bcrypt->create($this->request->getPost("password"));
            
			//Establecemos como datos a autenticar los que nos llegan del formulario
            $authAdapter->setIdentity($this->getRequest()->getPost("email"))
                        ->setCredential($securePass);
            
           
		   //Le decimos al servicio de autenticación que el adaptador
		   $auth->setAdapter($authAdapter);
		   
		   //Le decimos al servicio de autenticación que lleve a cabo la identificacion
           $result=$auth->authenticate();
         
		   //Si el resultado del login es falso, es decir no son correctas las credenciales
           if($authAdapter->getResultRowObject()==false){
		   
			   //Crea un mensaje flash y redirige
               $this->flashMessenger()->addMessage("Credenciales incorrectas, intentalo de nuevo");
               return $this->redirect()->toUrl($this->getRequest()->getBaseUrl().'/usuarios/login');
           }else{
		   
		     // Le decimos al servicio que guarde en una sesión 
			 // el resultado del login cuando es correcto
             $auth->getStorage()->write($authAdapter->getResultRowObject());
			 
			 //Nos redirige a una pagina interior
             return $this->redirect()->toUrl($this->getRequest()->getBaseUrl().'/usuarios/dentro');
           }
        }      
		
        return new ViewModel(
                array("form"=>$form)
                );
    }
    
    public function dentroAction(){
	//Leemos el contenido de la sesión
         $identi=$this->auth->getStorage()->read();
		 
         if($identi!=false && $identi!=null){
            $datos=$identi;
         }else{
             $datos="No estas identificado";
         }
         
         return new ViewModel(
                array("datos"=>$datos)
                );
    }
    
    public function cerrarAction(){
		//Cerramos la sesión borrando los datos de la sesión.
        $this->auth->clearIdentity();
        return $this->redirect()->toUrl($this->getRequest()->getBaseUrl().'/usuarios/login');
    }
}

El formulario:

<?php
namespace Modulo\Form;

use Zend\Form\Element;
use Zend\Form\Form;
use Zend\Form\Factory;

class LoginForm extends Form
{
    public function __construct($name = null)
     {
        parent::__construct($name);
        
      // $this->setInputFilter(new \Modulo\Form\AddUsuarioValidator());
        
       $this->setAttributes(array(
            //'action' => $this->url.'/modulo/recibirformulario',
            'action'=>"",
            'method' => 'post'
        ));
        
        $this->add(array(
            'name' => 'email',
            'attributes' => array(
                'type' => 'email',
                'class' => 'input form-control',
                'required'=>'required'
            )
        ));
        
         $this->add(array(
            'name' => 'password',
            'attributes' => array(
                'type' => 'password',
                'class' => 'input form-control',
                'required'=>'required'
            )
        ));
         
        $this->add(array(
            'name' => 'submit',
            'attributes' => array(     
                'type' => 'submit',
                'value' => 'Entrar',
                'title' => 'Entrar',
                'class' => 'btn btn-success'
            ),
        ));
 
     }
}

?>

Las vistas:

Login.phtml

<h1>Login en Zend Framework 2</h1>
<hr/>

<?php
$this->headTitle("Login usuarios");
$form = $this->form;
$form->prepare();
echo $this->form()->openTag($form);
?>
<div class="form_element">
<?php
    $email = $form->get('email');
    echo "Correo: ".$this->formInput($email);
    if(isset($error["email"])){
      echo $error["email"]['emailAddressInvalidHostname'];
    }
?>
</div>
<div class="form_element">
<?php
    $pass = $form->get('password');
    echo "Contraseña: ".$this->formInput($pass);
    echo $this->formElementErrors($pass);
?>
</div>

<?php 
echo $this->flashMessenger()->render();

echo $this->formElement($form->get('submit'));
echo $this->form()->closeTag(); 
?>

autenticacion en zend framework 2 login con zf2

Dentro.phtml

<?php 
//Comprobamos si nos llega la sesión correcta o no, esto se puede hacer de distintas formas
if(!is_string($this->datos)){
var_dump($this->datos->id);
echo "Bienvenido ".$this->datos->nombre." ".$this->datos->apellido."<br/>";
echo "Estas identificado con ".$this->datos->email;
?>
<p>
    <a class="btn btn-success" href="<?=$this->basePath("usuarios/cerrar")?>">Cerrar sesión</a>
</p>   
<?php  
}else{
    echo $this->datos;
}
?>

autenticacion en zend framework 2

Este componente es muy amplio, nos permite hacer mas cosas.

Más información:
Autenticación en la documentación oficial de Zend Framework 2

Víctor Robles WEB

Autor: Victor

Desarrollador web - Formador online - Blogger

Compartir este post

14 Comentarios

  1. Estoy aprendiendo a crear aplicaciones web con Zend Framework 2, y la verdad que me gusto mucho tu tutorial para aplicar el módulo de Login de usuarios; pero veo que falta el modelo de la base de datos «UsuariosModel» que no lo encuentra. Le agradecería si pudiera explicarme esta parte.

    Un saludo, y muchas gracias de antemano. 😉

    Responder
    • Ese es un modelo que tengo yo creado ahí, en realidad no es necesario para hacer funcionar la autenticación, lo que pasa es que realmente en un controlador no tendrás solo el método de login sino que tendrás más y necesitaras interaccionar con algún modelo.

      Responder
  2. Tienes una idea de porque en localhost me funciona perfectamente y al subirlo al servidor web no redirecciona y me muestra la vista por default? no obodece ninguna condición y el redireccionamiento no lo hace. saludos

    Responder
  3. Podrias dejar el repositorio en github de cada modulo … muy buen tutorial 😀

    Responder
  4. Estimado, muy buen tutorial… pero tengo algunas dudas. La tabla de usuarios en el que se guarda el email y la contraseña no tiene un campo de isActivo (BIT) o algo por el estilo. Se puede utilizar el mismo $authAdapter? En caso contrario, si realizo estas consultas manualmente… despues cuando yo mismo compruebe este tercer campo solo utilizaria la función $auth->getStorage()->write(array_personalizado);?.

    Atento a tus comentarios.

    Responder
  5. Estimado, podría subir su código para poder descargar 🙂

    Responder
  6. Excelente tutorial, pero no me puedo loguear, ingreso correctamente el correo y la contraseña que está en la BD, pero mi campo password no está encriptada, tendrá algo que ver eso? y si fuera el caso como debería proceder? Desde ya muchas gracias.

    Responder
    • Si tu password no está encriptada no uses el método que las encripta, pasale los datos limpios que le llegan por post.

      Responder
  7. Existe el mismo ejemplo para Zend 1?

    Me seria muy util, gracias!

    Responder
    • No, yo solo tengo tutoriales y un curso completo de ZF2. Saludos 😉

      Responder
  8. Hola, he revisado en otros tutoriales de ZF2 que ingresan codigo (listeners) en el Module.php y en este ejemplo no, la verdad este dilema me hace dudar sobre que version que autenticacion usar, ¿me podrias explicar algo al respecto?

    Saludos.

    Responder
    • Yo usaría lo más sencillo, si te parece más sencillo usar Listeners usa Listeners, si te parece más fácil hacerlo de esta forma hazlo de esta.

      Saludos 🙂

      Responder
  9. Hola, excelente tutorial, ya puedo usar login con una tabala, solo que intento hacer lo mismo pero con referencia de dos tablas y no encuentro la forma de hacerlo, espero me pueda orientar,

    Responder

Poner un comentario

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