sábado, 14 de enero de 2023

CRUD POO PHP MVC (PROYECTO STAR CRUD PARTE 2) Login y Sesiones

 



Vista login.php

Ahora que podemos registrar usuarios ha llegado el momento de permitir que nuestros usuarios usuario puedan logearse en nuestro CRUD. Para ello vamos a crear una nueva vista que llamaremos login.php y que será muy parecida a register.php, pero en este caso solo necesitaremos dos inputs en el form, user y password, vamos a ello:

CREANDO LA VISTA LOGIN

Vamos a nuestra carpeta views y creamos el archivo login.php:


Copiaremos y pegaremos la vista de register, pero haremos algunos cambios al formulario.

  • -        Eliminaremos el input para el user name
  • -        Cambiaremos el nombre al botón submit
  • -        Cambiaremos el name a los inputs email y password
 

·        En el action del form seguimos mandando la data al controlador gestionvista (en rojo)

  • ·        Al input para el email lo llamaremos login_email_txt (en verde)
  • ·        Al input para el passwor lo llamaremos login_password_txt (en violeta)
  • ·        Al botón submit lo llamaremos login_btn (en azul)


<!-- Hero form -->
<!-- Hero -->
<div class="p-5 text-center rounded-3">
  <div class="mask">
    <div class="d-flex justify-content-center align-items-center">
      <!--Form-->
      <form class="myform" name="login_frm" action="../controllers/gestionvista.php" method="post" enctype="multipart/form-data">
      <h2>Login</h2>
      <br>  
       <div class="mb-3">
         <label for="exampleInputEmail1" class="form-label">Email address</label>
         <input type="email" name="login_email_txt" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp">
         <div id="emailHelp" class="form-text cuote">We'll never share your email with anyone else.</div>
       </div>
       <div class="mb-3">
         <label for="exampleInputPassword1" class="form-label">Password</label>
         <input type="password" name="login_password_txt" class="form-control" id="exampleInputPassword1">
       </div>
         <button type="submit" name="login_btn" class="btn btn-dark">Submit</button>
      </form>    
      <!--End form-->
    </div>
  </div>
</div>
<!-- Hero -->

Recogiendo los datos de login en el controlador gestionvista.php

Vamos a crear un nuevo método en nuestro controlador gestionvista que se encarge de recoger los datos del formularo de login que estamos enviando desde la vista de logín, del mismo modo que lo hacíamos con register y solo para asegurarnos de que recibimos bien el mail y el pass los imprimimos por pantalla:

//Recogemos los datos del formulario login por el nombre del botón de submit, en este caso lo hemos llamado login_btn
if(isset($_POST["login_btn"]))
{
    //recojemos los datos en variables podemos llamar a las variables como en la función register ya que estas viven solo en este scope.
    $u_email = $_POST["login_email_text"];
    $u_password = $_POST["login_password_txt"];
    echo "Email: ".$u_email." password: ".$u_password." ";



Si hacemos clic en el submit y mandamos los datos a gestiónvista.php podemos ver la salida en pantalla:


Ahora que sabemos que estamos recibiendo correctamente estos datos, es momento de crear nuestros métodos para hacer login y vamos a ir hacia atrás, es decir desde el modelo tusers.phpàtcontrol.phpà hasta gestionvista.php.

Nos ocuparemos primero de crear el método login en el modelo tusers.php

   public function login()
   {
       //No es necesario comprobar previamente si el usuario existe ya que lo que queremos es hacer login si existe.
       $res = false;
 
       //Realizamos la consulta sql buscando el mail y el pass recibido,  para comprobar las credenciales del usuario usando el método consult_SQL del modelo dbaccess.
       if($this->dba->consult_SQL(" SELECT *  FROM users WHERE email = '". $this->email."' "))
       {
           //Si la consulta ha tenido éxito accedemos a la fila de resultados usando el método de dbaccess consult_row
           if(this->dba->consult_row() > 0){
             //Si hemos encontrado una fila de resultados de momento vamos a sólo a imprimirla para ver si funciona.
             $res = $this->dba->consult_row();
             echo $res;
           }
       }
   }

Es importante que a variable $this->email, vaya entre doble comillado para que en la consylta se lea sua valor como cadena de texto, de lo contrario no funcionará.

Ya tenemos preparado el método login en el modelo tuser.php vamos ahora a nuestro controlador principal tcontrol.php y crearemos un método que podemos llamará userLogin para seguir con la nomencaltura de los métodos:

En este caso sólo necesitamos como payload el mail y el password pero para la instancia le pasamos todo el payload que necesita la clase:

public function userLogin($u_mail, $u_password)
{
  //Creamos una instancia de la clase Tusers y aunqye no necesitamos el u_name lo incluimos en el payload del método.
  $u_login = new Tuser($u_name, $u_email, $u_password, $this->host, $this->user, $this->password, $this->db);
  {
    //Invocamos el método login d ela clase Tuser y lo guardamos en la variable de res.
    $res = $u_login->login();
    return $res;
  }
}

Por último, regresamos a gestionvista, donde vamos a crear una instancia de la case Tcontrol y a invocar el método que acabamos de crear userLogin, pasándole en el payload los datos de conexión, el mail y el pass recibidos y el username lo dejaremos en null.

//Recogemos los datos del formulario login por el nombre del botón de submit, en este caso lo hemos llamado login_btn
if(isset($_POST["login_btn"]))
{
    //recojemos los datos en variables podemos llamar a las variables como en la función register ya que estas viven solo en este scope.
    $u_email = $_POST["login_email_txt"];
    $u_password = $_POST["login_password_txt"];
 
   // echo "Email: ".$u_email." password: ".$u_password." ";
 
    //Creamo un objeto de la clase Tcontrol
    $u_l = new Tcontrol();
    //Invocamos el método userLogin pasando en el payload lo que necesita menos el username que lo enviaremos en null.
    $login_user = $u_l->userLogin("", $u_email, $u_password);
    echo $login_user;
}

 Ya podemos probar nuestro sistema de login, estamos registrados con el mail y el password que tu hayas usado para registrate.

Vamos a hacer login con las credenciales correctas a ver si se nos muestra nuestro mensaje de extio


Si introducimos el mail y la contraseña correctos el mensaje de éxito se muestra:

Si introducimos alguna credencial no válida:


Todo está funcionando correctamente, debemos ahora pasar a iniciar sesión de usuario

 

Creando la sesión de usuario logeado.

Vamos a ver qué es lo que tenemos hasta ahora:


Como podemos ver en el esquema, la secuencia es la siguiente:

1.      En login.php (vista) el usuario introduce su user y password, que previamente a registrado, el formulario envía estos datos vía POST a gestionvista.php.

2.     gestionvista.php (controladores) hemos incluido el archivo tcontrol.php, creamos un objeto de la clase Tcontrol, que llamamos $u_l para poder acceder al método userLogin() de la clase Tcontrol y le pasamos el payload que necesita, retornamos la respuesta del método login() de la clase Tcontrol.

3.    tcontrol.php (controladores)  incluimos el archivo tusers.php, creamos un objeto de la clase Tuser() que llamamos $u_login para poder acceder al método de la clase Tuser login(), usamos el método user_exists de la clase Tcontrol para asegurarnos que el usuario existe.

4.    tusers.php en tusers (modelos) recibimos como payload, todo lo que necesitamos saber, user, password, y credenciales de la base de datos, además sabemos ya que el usuario si existe en nuestra base de datos. Y esta clase se encarga de todo lo relacionado con la base de datos.

Respuestas encadenadas.

Si el loggeo ha tenido éxito, las respuestas se desencadenan de un método a otro desde los modelos a los controladores, del siguiente modo:

 

gestionvista.phpßtcontrol.phpßtusers.phpàdbaccess.php

Al final la respuesta iniciada a en tusers.php se traslada hasta el controlador gestionvista.php que se encargará de mostrar la vista que allí le indiquemos, ahora mimo solo hemos lanzado la información del usuario que se ha logeado, y por tanto se nos muestra esa información en gestionvista.php:

   public function login()
   {
       //No es necesario comprobar previamente si el usuario existe ya que lo que queremos es hacer login si existe.
       $res = false;
       //Realizamos la consulta sql buscando el mail y el pass recibido,  para comprobar las credenciales del usuario usando el método consult_SQL del modelo dbaccess.
       if($this->dba->consult_SQL(" SELECT * FROM users WHERE email = '".$this->email."' AND password = '".$this->password."'  "))
       {
           //La consulta la realiza con éxito el usuario existe.
           if(($this->dba->consult_row()))  
           {
               //Accedemos a los datos del usuario logeado
               if ($this->dba->consult_data('email'))
               {
                  $logged_user_name = ($this->dba->consult_data('username'));
                  $logged_user_email = ($this->dba->consult_data('email'));
                  $res = "El usuario : ".$logged_user_name." con email: ".$logged_user_email." ,Ha hecho login ";
               }
           }
           else
           {
             $res = true;  //Hacemos true la respuesta
           }
      }
      return $res;
  }

 

Lo que queremos hacer es que una vez el usuario se ha logeado lo queremos enviar a una página donde ya se pueda crear, editar o eliminar un registro y queremos que esa página esté protegida con sesiones de PHP. Por tanto, vanos a crear esa página protegida.

Lo primero será crear en el método login() de la clase tusers las variables de sesión en el array global $_SESSION[] y abriremos una sesión con el id del usuario, esta sesión será usada en la página del CRUD crud.php que vamos a proteger, además tendremos que crear un nuevo método púnlico aquí en tusers, para que el usuario pueda cerrar la sesión. Vamos a ver cómo:

   public function login()
   {
       //No es necesario comprobar previamente si el usuario existe ya que lo que queremos es hacer login si existe.
       $res = false;
       //Realizamos la consulta sql buscando el mail y el pass recibido,  para comprobar las credenciales del usuario usando el método consult_SQL del modelo dbaccess.
       if($this->dba->consult_SQL(" SELECT * FROM users WHERE email = '".$this->email."' AND password = '".$this->password."'  "))
       {
           //La consulta la realiza con éxito el usuario existe.
           if(($this->dba->consult_row()))  
           {
               //Accedemos a los datos del usuario logeado
               if ($this->dba->consult_data('email'))
               {
                  //$logged_user_name = ($this->dba->consult_data('username'));
                  //$logged_user_email = ($this->dba->consult_data('email'));
                  //$res = "El usuario : ".$logged_user_name." con email: ".$logged_user_email." ,Ha hecho login ";
 
                  //Aqui debemos de iniciar sesión de usuuario
                  //Creamos las varaibles de sesión en el array global $_SESSION[]
 
                  //Iniciamos una sesión
                  session_start();
                  //Creamos una variable que se haga true si el login ha tenido éxito
                  $_SESSION['login'] = true;
                  //Creamos otra variable consultando los datos del usuario acceiendo a su username
                  $_SESSION['id'] = ($this->dba->consult_data('username'));
 
                  //dirigimos al usuario con sesión abierta a la página principal del CRUD
                  header('Location: ../views/crud.php');
               }
           }
           else
           {
          //Si la consulta no tiene éxito mandamos mensaje de error y redirigimos al login.
          echo "<script language='javascript'>
          alert('mail or user not valid');
          location='../views/login.php';
          </script>";
           }
      }
 
      return $res;
  }

 

Vamos a crear ahora esa página crud.php la crearemos en vistas:




De momento solo crearemos una estructura html5 con un mensaje h1 :

<!DOCTYPE html>
<html lang="eS">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CRUD</title>
</head>
<body>
   <h1> Página protegida con sesiones</h1>
</body>
</html>
 

Ahora si nos logeamos correctamente se nos redirige a la página crud.php mientras que si las credenciales no son válidas se nos devuelve al login previo mensaje de error:

Login correcto:

Ahora necesitamos ir a nuestra nueva vista crud.php para iniciar allí sesión y comprobar si realmente el usuario que accede tiene sesión activa, es decir vamos a proteger esta ruta:

<?php
//Vuelvo a iniciar sesión para poder usar $_SESSION
session_start();
 
if( $_SESSION['login'] != true  ) //Si no hay una sesión activa
{
    //Enviamos al usuario al login
    header('Location: ../views/login.php');
}
//NO hace falta un else, si no hay sesión todo lo demas no se renderiza.
?>
 
<!DOCTYPE html>
<html lang="eS">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CRUD</title>
</head>
<body>
   <h1> Página protegida con sesiones</h1>
</body>
</html>

 

Si ahora copio la ruta de la página crud.php



Y me voy a otro navegador y la pego, me daré cuenta de que automáticamente la aplicación me manda al login sin poder entrar al CRUD, porque no estoy autenticado:


Lo que necesitamos ahora es crear un método en gestionavista que nos destruya la sesión, de forma que el usuario pueda cerrar sesión antes de abandonar la página protegida.

Podríamos usar un sencillo link a un archivo php que se ocupara exclusivamente de ello, pero recuerda estamos trabajando con el modelo MVC y disponemos del archivo gestionavista.php que es el controlador de vistas, por ello lo que vamos a ahacer es añadir un botón tipo submit, para poder recoger la acción desde gestionavista.php y ahí destruir la sesión, veamos cómo:

Vamos a nuestro archivo crud.php y hacemos:

 <?php
//Vuelvo a iniciar sesión para poder usar $_SESSION
session_start();
 
if( $_SESSION['login'] != true  ) //Si no hay una sesión activa
{
    //Enviamos al usuario al login
    header('Location: ../views/login.php');
}
//NO hace falta un else, si no hay sesión todo lo demas no se renderiza.
?>
 
<!DOCTYPE html>
<html lang="eS">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CRUD</title>
</head>
<body>
   <h1> Página protegida con sesiones</h1>
   <form class="myform" name="close_session_frm" action="../controllers/gestionvista.php" method="post" enctype="multipart/form-data">
     <input type="submit" name="close_session_btn" value="Close session">
   </form>
</body>
</html>

Ahora si nos logeamos, veremos el botón de cerrar sesión

 





No hay comentarios:

Publicar un comentario