Diferencia entre revisiones de «Usuario:ManuelRomero/php/smarty/login1»

De WikiEducator
Saltar a: navegación, buscar
(Página creada con «{{:Usuario:ManuelRomero/php/smarty/tienda1/nav}}»)
 
Línea 1: Línea 1:
 
{{:Usuario:ManuelRomero/php/smarty/tienda1/nav}}
 
{{:Usuario:ManuelRomero/php/smarty/tienda1/nav}}
 +
 +
===La lógica===
 +
*Generaremos el fichero '''''login.php'''''
 +
*Su función es autentificar al usuario de la aplicación web.
 +
*Todos los usuarios de la aplicación deberán autentificarse utilizando esta página antes de poder acceder al resto de páginas.
 +
*La siguiente imagen muestra un caso de uso de este escenario
 +
[[Archivo:tiendaLogin.png]]
 +
;Descripcion de la imagen
 +
#Login pedirá un usuario y contraseña para validar
 +
#Al darle a validar, se validará el usuario contra la base de datos.
 +
#Si no es ok mostrará un error y seguiremos en '''''login.php''''', si es correcto iremos a '''''productos.php'''''
 +
Para este escenario necesitaremos los siguientes ficheros según vemos en la imagen
 +
 +
[[Archivo:tiendaLogin2.png]]
 +
;Descripción de la imagen
 +
 +
#El cliente invoca al fichero login.php
 +
#Este método solicitará usuario y contraseña visualizando la plantilla login.tpl
 +
#Cuando presionemos enviar validará contra la base de datos
 +
#Si todo ok, mostrará la plantilla productos.tpl;
 +
#Si no se ha validado, mostrará la plantilla login.tpl con el error encontrado
 +
*Para implementar esta parte del proyecto necesitaremos desarrollar los siguientes ficheros
 +
#DB.php (clase)
 +
#login.php (lógica)
 +
#productos.php (lógica sin contenido)
 +
#login.tpl (presentacion).
 +
 +
===Desarrollando el código===
 +
;DB.php
 +
*Esta es una  clase que mantendrá todo el acceso a la base de datos
 +
*De momento solo necesito un método de validar el usuario
 +
*Este método tendrá que hacer 3 cosas:
 +
#conectar a la base de datos,
 +
#realizar una consulta,
 +
#verificar que la consulta contenga un registro (OK! Usuario existe), o no (Usuario no registrado)
 +
*Seguramente otros métodos tengan que hacer estas acciones (conectar, ejecutar consultas, …), por lo que estas acciones será métodos privados de la clase.
 +
*Para poder pasar parámetros a la hora de ejecutar la consutla usaremos '''''PDO''''' en lugar de '''''mysqli'''''
 +
[[Archivo:DB.png]]
 +
*El código de esta clase
 +
<source lang=php>
 +
<?php
 +
 +
 +
class DB {
 +
    //atributo privado de conexión
 +
    private static $conexion;
 +
   
 +
  /*======================conectar()======================================
 +
    conecta con la base de datos, usando PDO
 +
    da valor al atributo privado y estático $conexion de la clase
 +
    En caso de no conectarse aborta la app y muestra un mensaje
 +
  ****************************************************************************************** */
 +
    private static function conectar(){
 +
        $opc = array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8");
 +
        $dsn = "mysql:host=localhost;dbname=manuel_dwes";
 +
        $usuario = 'root';
 +
        $contrasena = 'root';
 +
        try{
 +
          $conexion= new PDO($dsn, $usuario, $contrasena, $opc);
 +
          $conexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 +
        }catch (PDOException $e) {
 +
            die ('Abortamos la aplicación por fallo conectando con la BD' . $e->getMessage());
 +
        }
 +
        self::$conexion = $conexion;
 +
   
 +
}
 +
 +
 +
/*======================ejecutaConsulta ($sql,$valores)======================================
 +
    Accion: Ejecuta una consulta preparada con los valores de los parámetros de la consulta preparada
 +
    Parámetros: $sql es la consulta preparada y parametrizada
 +
                $valores es un array asociativo con los valores de los distintos
 +
                          parámetros de la consulta anterior
 +
    Retorna =La consulta despues de ejecutarla, o null si no la ha podido ejecutaqr
 +
            en caso de no ejecutarla da un mensaje             
 +
* ***********************************************************************************************/
 +
    protected static function ejecutaConsulta($sql,$valores) {
 +
      if (self::$conexion == null)
 +
            self::conectar();
 +
      $conexion = self::$conexion;
 +
      try{
 +
          $consulta = $conexion->prepare($sql);
 +
          $consulta->execute($valores);
 +
      }catch (PDOException $e) {
 +
          echo 'No se ha podido ejecutar la consulta' . $e->getMessage();
 +
          return null;
 +
        }
 +
      return $consulta;
 +
     
 +
    }
 +
 +
 +
/*======================verificaCliente ($nombre,$pass)======================================
 +
    Accion: verifica si un nombre y pass son contenidos en la base de datos
 +
    Parámetros: $nombre es el nombre de usuario
 +
                $pass es la password para ese nombre
 +
    Retorna  true o false según se haya podido o no validar
 +
  * Recordar que la pass está cifrada con md5 en la base de datos     
 +
* ***********************************************************************************************/ 
 +
    public static function verificaCliente($nombre, $pass) {
 +
      $valores = array('usuario'=>$nombre, 'password' =>$pass);
 +
      $sql = <<<FIN
 +
        SELECT usuario FROM usuarios
 +
        WHERE usuario=:usuario
 +
        AND contrasena=md5(:password)
 +
FIN;
 +
      $resultado = self::ejecutaConsulta ($sql,$valores);
 +
      $verificado = false;
 +
      if ($resultado->fetch())
 +
          $verificado=true;
 +
      return $verificado;
 +
    }
 +
}//End de la clase DB.php
 +
 +
?>
 +
</source>
 +
;login.php
 +
*Este fichero implementa las acciones especificadas anteriormente
 +
*Cargamos la librería de smarty
 +
*Realizamos la lógica
 +
*Exportamos la variable '''''$error''''' para la plantilla
 +
*Visualizamos  la plantilla
 +
*El código se exporta a continaución
 +
<source lang=php>
 +
<?php
 +
require_once('./../include/DB.php');
 +
 +
// Cargamos la librería de Smarty
 +
require_once('Smarty.class.php');
 +
$smarty = new Smarty;
 +
$smarty->template_dir = '/web/smarty/tiendaSmarty/templates/';
 +
$smarty->compile_dir = '/web/smarty/tiendaSmarty/templates_c/';
 +
$smarty->config_dir = '/web/smarty/tiendaSmarty/configs/';
 +
$smarty->cache_dir = '/web/smarty/tiendaSmarty/cache/';
 +
// Verificaamos si queremos validar los datos del formulario o solo visualizar el formulario (login.tpl)
 +
if (isset($_POST['enviar'])) {
 +
    $usuario =  $_POST['usuario'];
 +
    $pass = $_POST['password'];
 +
    if ((empty($usuario)) || (empty($pass)))
 +
        $smarty->assign('error','Debes introducir un nombre de usuario y una contraseña');
 +
    else {
 +
        // Comprobamos las credenciales con la base de datos
 +
        if (DB::verificaCliente($usuario, $pass)) {
 +
            session_start();
 +
            $_SESSION['usuario']=$usuario;
 +
            header("Location: producto.php");                   
 +
        }
 +
        else {
 +
            // Si las credenciales no son válidas, se vuelven a pedir
 +
            $smarty->assign('error','Usuario o contraseña no válidos!');
 +
        }
 +
    }
 +
}
 +
// Mostramos la plantilla
 +
$smarty->display('login.tpl');
 +
?>
 +
</source>
 +
;login.tpl
 +
*La plantilla tiene la parte de html
 +
*Lo único que visualiza es el código de error en caso de que lo hubiera
 +
<source lang=php>
 +
<!DOCTYPE html>
 +
{*Plantilla para login. Es invocada desde login.php. solo visualiza el $error del php*}
 +
<html>
 +
<head>
 +
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 +
  <title>Login Tienda Web con Plantillas</title>
 +
  <link href="tienda.css" rel="stylesheet" type="text/css">
 +
</head>
 +
<body>
 +
    <div id='login'>
 +
    <form action='login.php' method='post'>
 +
    <fieldset >
 +
        <legend>Login</legend>
 +
        {*si la variable error tiene algún valor se visualiza*}
 +
        <div><span class='error'>{$error}</span></div>
 +
        <div class='campo'>
 +
            <label for='usuario' >Usuario:</label><br/>
 +
            <input type='text' name='usuario' id='usuario' maxlength="50" /><br/>
 +
        </div>
 +
        <div class='campo'>
 +
            <label for='password' >Contraseña:</label><br/>
 +
            <input type='password' name='password' id='password' maxlength="50" /><br/>
 +
        </div>
 +
 +
        <div class='campo'>
 +
            <input type='submit' name='enviar' value='Enviar' />
 +
        </div>
 +
    </fieldset>
 +
    </form>
 +
    </div>
 +
</body>
 +
</html>
 +
 +
</source>
 +
;productos.php
 +
*En esta primera parte del proyecto estos ficheros solo contienen información básica,
 +
*Se implementará en la segunda parte del desarrollo
 +
<source lang=php>
 +
<?php
 +
require_once('Smarty.class.php');
 +
// Recuperamos la información de la sesión
 +
session_start();
 +
// Y comprobamos que el usuario se haya autentificado, para evitar que puedan acceder directamente
 +
//a esta pagina sin pasar por el login
 +
if (!isset($_SESSION['usuario']))
 +
    die("Error - debe <a href='login.php'>identificarse</a>.<br />");
 +
// Cargamos la librería de Smarty
 +
$smarty = new Smarty;
 +
 +
$smarty->template_dir = '/web/smarty/tiendaSmarty/templates/';
 +
$smarty->compile_dir = '/web/smarty/tiendaSmarty/templates_c/';
 +
$smarty->config_dir = '/web/smarty/tiendaSmarty/configs/';
 +
$smarty->cache_dir = '/web/smarty/tiendaSmarty/cache/';
 +
//De momento solo visualizamos que el usuario
 +
$smarty->assign("usuario",$_SESSION['usuario']);
 +
//Ahora mostramos la plantilla
 +
$smarty->display("producto.tpl");
 +
?>
 +
</source>
 +
;producto.tpl
 +
*La plantilla del producto
 +
*Simplemente una página de información de lo que hará
 +
<source lang = php>
 +
<!DOCTYPE html>
 +
{*Platilla para visualizar los productos, se invoca desde productos.php*}
 +
<html>
 +
    <head>
 +
        <title>práctica de tienda página de productos </title>
 +
        <meta charset="UTF-8">
 +
    </head>
 +
    <body>
 +
      {*primero solo visualizaremos que el usuario está conectado*}
 +
      <h1>Bienvenido a esta página {$usuario}</h1>
 +
      <hr/>
 +
      <h3>En breve visualizará una lista de productos para hacer su compra</h3>
 +
     
 +
    </body>
 +
</html>
 +
</source>
 +
*Este código puede verse funcionado
 +
http://www.manuel.infenlaces.com/tiendaSmarty/v1/logica/login.php

Revisión de 01:56 15 mar 2017



La lógica

  • Generaremos el fichero login.php
  • Su función es autentificar al usuario de la aplicación web.
  • Todos los usuarios de la aplicación deberán autentificarse utilizando esta página antes de poder acceder al resto de páginas.
  • La siguiente imagen muestra un caso de uso de este escenario

TiendaLogin.png

Descripcion de la imagen
  1. Login pedirá un usuario y contraseña para validar
  2. Al darle a validar, se validará el usuario contra la base de datos.
  3. Si no es ok mostrará un error y seguiremos en login.php, si es correcto iremos a productos.php

Para este escenario necesitaremos los siguientes ficheros según vemos en la imagen

TiendaLogin2.png

Descripción de la imagen
  1. El cliente invoca al fichero login.php
  2. Este método solicitará usuario y contraseña visualizando la plantilla login.tpl
  3. Cuando presionemos enviar validará contra la base de datos
  4. Si todo ok, mostrará la plantilla productos.tpl;
  5. Si no se ha validado, mostrará la plantilla login.tpl con el error encontrado
  • Para implementar esta parte del proyecto necesitaremos desarrollar los siguientes ficheros
  1. DB.php (clase)
  2. login.php (lógica)
  3. productos.php (lógica sin contenido)
  4. login.tpl (presentacion).

Desarrollando el código

DB.php
  • Esta es una clase que mantendrá todo el acceso a la base de datos
  • De momento solo necesito un método de validar el usuario
  • Este método tendrá que hacer 3 cosas:
  1. conectar a la base de datos,
  2. realizar una consulta,
  3. verificar que la consulta contenga un registro (OK! Usuario existe), o no (Usuario no registrado)
  • Seguramente otros métodos tengan que hacer estas acciones (conectar, ejecutar consultas, …), por lo que estas acciones será métodos privados de la clase.
  • Para poder pasar parámetros a la hora de ejecutar la consutla usaremos PDO en lugar de mysqli

DB.png

  • El código de esta clase
<?php
 
 
class DB {
    //atributo privado de conexión
    private static $conexion;
 
  /*======================conectar()======================================
     conecta con la base de datos, usando PDO
     da valor al atributo privado y estático $conexion de la clase
     En caso de no conectarse aborta la app y muestra un mensaje
   ****************************************************************************************** */
    private static function conectar(){
        $opc = array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8");
        $dsn = "mysql:host=localhost;dbname=manuel_dwes";
        $usuario = 'root';
        $contrasena = 'root';
        try{
           $conexion= new PDO($dsn, $usuario, $contrasena, $opc);
           $conexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }catch (PDOException $e) {
             die ('Abortamos la aplicación por fallo conectando con la BD' . $e->getMessage());
         }
         self::$conexion = $conexion;
 
}
 
 
/*======================ejecutaConsulta ($sql,$valores)======================================
    Accion: Ejecuta una consulta preparada con los valores de los parámetros de la consulta preparada
    Parámetros: $sql es la consulta preparada y parametrizada
                $valores es un array asociativo con los valores de los distintos 
                          parámetros de la consulta anterior
    Retorna =La consulta despues de ejecutarla, o null si no la ha podido ejecutaqr
             en caso de no ejecutarla da un mensaje              
 * ***********************************************************************************************/
    protected static function ejecutaConsulta($sql,$valores) {
       if (self::$conexion == null)
            self::conectar();
       $conexion = self::$conexion;
       try{
           $consulta = $conexion->prepare($sql);
           $consulta->execute($valores);
       }catch (PDOException $e) {
           echo 'No se ha podido ejecutar la consulta' . $e->getMessage();
           return null;
        }
       return $consulta;
 
    }
 
 
 /*======================verificaCliente ($nombre,$pass)======================================
    Accion: verifica si un nombre y pass son contenidos en la base de datos
    Parámetros: $nombre es el nombre de usuario
                $pass es la password para ese nombre
    Retorna  true o false según se haya podido o no validar
  * Recordar que la pass está cifrada con md5 en la base de datos      
 * ***********************************************************************************************/   
    public static function verificaCliente($nombre, $pass) {
       $valores = array('usuario'=>$nombre, 'password' =>$pass);
       $sql = <<<FIN
        SELECT usuario FROM usuarios 
        WHERE usuario=:usuario
        AND contrasena=md5(:password)
FIN;
       $resultado = self::ejecutaConsulta ($sql,$valores);
       $verificado = false;
       if ($resultado->fetch())
          $verificado=true;
       return $verificado;
    }
}//End de la clase DB.php
 
?>
login.php
  • Este fichero implementa las acciones especificadas anteriormente
  • Cargamos la librería de smarty
  • Realizamos la lógica
  • Exportamos la variable $error para la plantilla
  • Visualizamos la plantilla
  • El código se exporta a continaución
<?php
require_once('./../include/DB.php');
 
// Cargamos la librería de Smarty
require_once('Smarty.class.php');
$smarty = new Smarty;
$smarty->template_dir = '/web/smarty/tiendaSmarty/templates/';
$smarty->compile_dir = '/web/smarty/tiendaSmarty/templates_c/';
$smarty->config_dir = '/web/smarty/tiendaSmarty/configs/';
$smarty->cache_dir = '/web/smarty/tiendaSmarty/cache/';
// Verificaamos si queremos validar los datos del formulario o solo visualizar el formulario (login.tpl)
if (isset($_POST['enviar'])) {
    $usuario =  $_POST['usuario'];
    $pass = $_POST['password'];
    if ((empty($usuario)) || (empty($pass))) 
        $smarty->assign('error','Debes introducir un nombre de usuario y una contraseña');
    else {
        // Comprobamos las credenciales con la base de datos
        if (DB::verificaCliente($usuario, $pass)) {
            session_start();
            $_SESSION['usuario']=$usuario;
            header("Location: producto.php");                    
        }
        else {
            // Si las credenciales no son válidas, se vuelven a pedir
            $smarty->assign('error','Usuario o contraseña no válidos!');
        }
    }
}
// Mostramos la plantilla
$smarty->display('login.tpl');
?>
login.tpl
  • La plantilla tiene la parte de html
  • Lo único que visualiza es el código de error en caso de que lo hubiera
<!DOCTYPE html>
{*Plantilla para login. Es invocada desde login.php. solo visualiza el $error del php*}
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>Login Tienda Web con Plantillas</title>
  <link href="tienda.css" rel="stylesheet" type="text/css">
</head>
<body>
    <div id='login'>
    <form action='login.php' method='post'>
    <fieldset >
        <legend>Login</legend>
        {*si la variable error tiene algún valor se visualiza*}
        <div><span class='error'>{$error}</span></div>
        <div class='campo'>
            <label for='usuario' >Usuario:</label><br/>
            <input type='text' name='usuario' id='usuario' maxlength="50" /><br/>
        </div>
        <div class='campo'>
            <label for='password' >Contraseña:</label><br/>
            <input type='password' name='password' id='password' maxlength="50" /><br/>
        </div>
 
        <div class='campo'>
            <input type='submit' name='enviar' value='Enviar' />
        </div>
    </fieldset>
    </form>
    </div>
</body>
</html>
productos.php
  • En esta primera parte del proyecto estos ficheros solo contienen información básica,
  • Se implementará en la segunda parte del desarrollo
<?php
require_once('Smarty.class.php');
// Recuperamos la información de la sesión
session_start();
// Y comprobamos que el usuario se haya autentificado, para evitar que puedan acceder directamente
//a esta pagina sin pasar por el login
if (!isset($_SESSION['usuario'])) 
    die("Error - debe <a href='login.php'>identificarse</a>.<br />");
// Cargamos la librería de Smarty
$smarty = new Smarty;
 
$smarty->template_dir = '/web/smarty/tiendaSmarty/templates/';
$smarty->compile_dir = '/web/smarty/tiendaSmarty/templates_c/';
$smarty->config_dir = '/web/smarty/tiendaSmarty/configs/';
$smarty->cache_dir = '/web/smarty/tiendaSmarty/cache/';
//De momento solo visualizamos que el usuario 
$smarty->assign("usuario",$_SESSION['usuario']);
//Ahora mostramos la plantilla
$smarty->display("producto.tpl");
?>
producto.tpl
  • La plantilla del producto
  • Simplemente una página de información de lo que hará
<!DOCTYPE html>
{*Platilla para visualizar los productos, se invoca desde productos.php*}
<html>
    <head>
        <title>práctica de tienda página de productos </title>
        <meta charset="UTF-8">
    </head>
    <body>
       {*primero solo visualizaremos que el usuario está conectado*}
       <h1>Bienvenido a esta página {$usuario}</h1>
       <hr/>
       <h3>En breve visualizará una lista de productos para hacer su compra</h3>
 
    </body>
</html>
  • Este código puede verse funcionado
http://www.manuel.infenlaces.com/tiendaSmarty/v1/logica/login.php