Diferencia entre revisiones de «Usuario:ManuelRomero/php/sesiones»

De WikiEducator
Saltar a: navegación, buscar
 
(Una revisión intermedia por el mismo usuario no mostrado)
Línea 1: Línea 1:
{{TEP}}
 
 
 
 
{{:Usuario:ManuelRomero/php/nav}}
 
{{:Usuario:ManuelRomero/php/nav}}
  
Línea 202: Línea 199:
  
 
}}
 
}}
===Ejemplo práctico===
 
*Vamos a hacer un ejemplo práctico en el que vamos a usar sesiones
 
*Consiste en implementar una tienda on line con los datos que venimos trabajando
 
*El siguiente diagrama muestra el escenario que queremos representar
 
[[Archivo:tienda1.png]]
 
*Explicación funcional de las páginas
 
;Login (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.
 
;Listado de productos (productos.php).
 
: Presenta un listado de los productos de la tienda, y permite al usuario seleccionar aquellos que va a comprar.
 
;Cesta de compra (cesta.php).
 
:Muestra un resumen de los productos escogidos por el usuario para su compra y da acceso a la página de pago.
 
;Pagar (pagar.php).
 
:Una vez confirmada la compra, la última página debería ser la que permitiera al usuario escoger el método de pago y la forma de envío.
 
:En esta aplicación simplemente mostrará un mensaje de tipo "Gracias por su compra" y ofrecerá un enlace para comenzar una nueva compra.
 
;Logoff (logoff.php).
 
:Esta página desconecta al usuario de la aplicación y redirige al usuario de forma automática a la pantalla de autentificación.
 
: No muestra ninguna información en pantalla, por lo que no es visible para el usuario.
 
*Para realizar esta práctiva vamos a utilizar la siguiente hoja de estilo, disponible en un fichero puesto en el moodle
 
*Observa los diferentes div definidos para poderlos utilizar como es el caso de '''''error'''''
 
<source lang=css>
 
.error {
 
  font-family: Verdana, Arial, sans-serif;
 
  font-size: 0.7em;
 
  color: #900;
 
  background-color : #ffff00;
 
}
 
 
.divisor {
 
  clear:both;
 
  height:0;
 
  font-size: 1px;
 
  line-height: 0px;
 
}
 
 
#login fieldset {
 
  position: absolute;
 
  left: 50%;
 
  top: 50%;
 
  width: 230px;
 
  margin-left: -115px;
 
  height: 160px;
 
  margin-top: -80px;
 
  padding:10px;
 
  border:1px solid #ccc;
 
  background-color: #eee;
 
}
 
 
#login legend {
 
  font-family : Arial, sans-serif;
 
  font-size: 1.3em;
 
  font-weight:bold;
 
  color:#333;
 
}
 
 
#login .campo {
 
  margin-top:8px;
 
  margin-bottom: 10px;
 
}
 
 
#login label {
 
  font-family : Arial, sans-serif;
 
  font-size:0.8em;
 
  font-weight: bold;
 
}
 
 
 
#login input[type="text"], #login input[type="password"] {
 
  font-family : Arial, Verdana, sans-serif;
 
  font-size: 0.8em;
 
  line-height:140%;
 
  color : #000;
 
  padding : 3px;
 
  border : 1px solid #999;
 
  height:18px;
 
  width:220px;
 
}
 
 
#login input[type="submit"] {
 
  width:100px;
 
  height:30px;
 
  padding-left:0px;
 
}
 
 
.pagproductos body, .pagcesta body  {
 
  font: 100% Verdana, Arial, Helvetica, sans-serif;
 
  background: #666;
 
  margin: 0;
 
  padding: 0;
 
  text-align: center;
 
  color: #000000;
 
}
 
 
#contenedor {
 
  width: 90%;
 
  background: #fff;
 
  margin: 0 auto;
 
  border: 1px solid #000;
 
  text-align: left;
 
}
 
 
#encabezado {
 
  padding: 0 10px;
 
  border-top-width: thin;
 
  border-right-width: thin;
 
  border-bottom-width: thin;
 
  border-left-width: thin;
 
  border-top-style: solid;
 
  border-right-style: solid;
 
  border-bottom-style: solid;
 
  border-left-style: solid;
 
  background-color: #9cf;
 
}
 
 
#encabezado h1 {
 
  margin: 0;
 
  padding: 10px 0;
 
}
 
.pagproductos #cesta {
 
  float: right;
 
  width: 12em;
 
  background-color: #588;
 
}
 
.pagproductos #cesta h3 {
 
  margin-left: 10px;
 
  margin-right: 10px;
 
}
 
.pagproductos #cesta p {
 
  margin-left: 10px;
 
  margin-right: 10px;
 
  font-size: 10px;
 
}
 
 
.pagproductos #cesta input[type="submit"] {
 
  margin-left: 10px;
 
  margin-right: 10px;
 
  margin-bottom: 3px;
 
  width:100px;
 
  height:30px;
 
  padding-left:0px;
 
}
 
 
.pagproductos #productos {
 
  margin: 0 10em 0 10px;
 
}
 
 
.pagcesta #productos {
 
  margin: 10px;
 
  font-size: 12px;
 
}
 
 
.pagproductos #productos input, .pagproductos #productos p {
 
  font-size: 10px;
 
}
 
 
#productos .codigo {
 
  width: 20%;
 
  float: left;
 
}
 
 
#productos .nombre {
 
  width: 60%;
 
  float: left;
 
}
 
 
#productos .precio {
 
  width: 20%;
 
  text-align: right;
 
  font-weight: bold;
 
}
 
 
#pie {
 
  padding: 0 10px;
 
  background-color: #99ccff;
 
  border-top-width: thin;
 
  border-right-width: thin;
 
  border-bottom-width: thin;
 
  border-left-width: thin;
 
  border-top-style: solid;
 
  border-right-style: solid;
 
  border-bottom-style: solid;
 
  border-left-style: solid;
 
}
 
</source>
 
==login.php==
 
*Usando la base de datos de usuarios validamos el usuario
 
*Ŝi queremos dar de alta más usuarios, se hará de forma administrativa directemente en la base de datos, es decir los usuarios ya existen en la base de datos, en nuestra aplicación no se pueden registrar (posible mejora
 
*Aquí ponemos la parte de html para empezar
 
*Observar una variable llamada error que visualiza información en caso de que algo no vaya bien
 
*El posible valor de esa variable ne el código php
 
<source lang=html5>
 
<!DOCTYPE html>
 
<!-- Desarrollo Web en Entorno Servidor -->
 
<!-- Ejemplo Tienda Web: login.php -->
 
<html>
 
<head>
 
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 
  <title>Ejemplo Tema 4: Login Tienda Web</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>
 
        <div><span class='error'><?php echo $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>
 
</html>
 
</source>
 
==producto.php==
 
*Esta es la página principal
 
*En este caso se deben listar todos los productos con la opción de poder incorporarlos a la cesta de la compra
 
*Además en ella vamos  ir llenando la cesta de la compra, con la opción de comprar o vaciar la cesta en un momento dado
 
*La página se divide en varias zonas, cada una definida por una etiqueta < div> en el código HTML:
 
 
#'''''encabezado'''''. Contiene únicamente el título de la página.
 
#'''''productos'''''. Contiene el listado de todos los productos tal y como figuran en la base de datos. Cada producto figura en una línea (nombre y precio).
 
*Se crea un formulario por cada producto, con un botón "Añadir" que envía a esta misma página los datos código, nombre y precio del producto.
 
*Cuando se abre la página, se comprueba si se ha enviado este formulario, y si fuera así se añade un elemento al array asociativo $_SESSION['cesta'] con los datos del nuevo producto.
 
*De cada producto se incluye el precio y el nombre
 
<source lang=php>
 
// Comprobamos si se ha enviado el formulario de añadir
 
    if (isset($_POST['enviar'])) {
 
        // Creamos un array con los datos del nuevo producto
 
        $producto['nombre'] = $_POST['nombre'];
 
        $producto['precio'] = $_POST['precio'];
 
        //  y lo añadimos
 
        $_SESSION['cesta'][$_POST['producto']] = $producto;
 
  }
 
</source>
 
*En la cabecera a la parte de la derecha tendremos información de la compra actual de la cesta, con la opción de comrar o vaciar nuestra cesta
 
<source lang=html5>
 
<html>
 
<head>
 
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 
  <title>Ejemplo Tema 4: Listado de Productos</title>
 
  <link href="tienda.css" rel="stylesheet" type="text/css">
 
</head>
 
 
<body class="pagproductos">
 
 
<div id="contenedor">
 
  <div id="encabezado">
 
    <h1>Listado de productos</h1>
 
  </div>
 
  <div id="cesta">
 
    <h3><img src="cesta.png" alt="Cesta" width="24" height="21"> Cesta</h3>
 
    <hr />
 
</source>
 
 
*En la parte inferior mantenemos la opción de desconectar
 
<source lang=php>
 
<br class="divisor" />
 
  <div id="pie">
 
    <form action='logoffW.php' method='post'>
 
        <input type='submit' name='desconectar' value='Desconectar usuario <?php echo $_SESSION['usuario']; ?>'/>
 
    </form>       
 
<?php
 
    if (isset($error)) {
 
        print "<p class='error'>Error $error: $mensaje</p>";
 
    }
 
?>
 
  </div>
 
</source>
 
;Importante:
 
*En cada página debemos verificar que el usuario está conectado
 
<source lang=php>
 
<?php
 
    // Recuperamos la información de la sesión
 
    session_start();
 
   
 
    // Y comprobamos que el usuario se haya autentificado
 
    if (!isset($_SESSION['usuario'])) {
 
        die("Error - debe <a href='login.php'>identificarse</a>.<br />");
 
    }
 
?>
 
</source>
 
==cesta.php==
 
*En esta página vamos a ver un resumen de todo lo que hemos comprado, así como del total de la compra
 
<source lang=php>
 
<html>
 
<head>
 
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 
  <title>Ejemplo Tema 4: Cesta de la Compra</title>
 
  <link href="tienda.css" rel="stylesheet" type="text/css">
 
</head>
 
 
<body class="pagcesta">
 
 
<div id="contenedor">
 
  <div id="encabezado">
 
    <h1>Cesta de la compra</h1>
 
  </div>
 
  <div id="productos">
 
<?php
 
    $total = 0;
 
    foreach($_SESSION['cesta'] as $codigo => $producto) {
 
  // ....... etc etc ....
 
 
?> //Fin del código php
 
      <hr />
 
      <p><span class='pagar'>Precio total: <?php print $total; ?> €</span></p>
 
      <form action='pagarW' method='post'>
 
          <p>
 
              <span class='pagar'>
 
                    <input type='submit' name='pagar' value='Pagar'/>
 
              </span>
 
          </p>
 
      </form>                 
 
  </div>
 
  <br class="divisor" />
 
  <div id="pie">
 
    <form action='logoffW' method='post'>
 
        <input type='submit' name='desconectar' value='Desconectar usuario <?php echo $_SESSION['usuario']; ?>'/>
 
    </form>       
 
  </div>
 
</div>
 
</body>
 
</html>
 
</source>
 
*De esta página como se ha comentado anteriormente tenemos la opción de pagar y de desconectar que anulará la cesta
 
 
==pagar.php==
 
*Simplemente informa de que se ha pagado correctamente.
 
*Nos volverá a llevar a poder realizar otra compra
 
==logoff.php==
 
*Desconecta la página y vuelve a login.php
 
 
 
  
 
{{Lectura|Title=Documentación|
 
{{Lectura|Title=Documentación|

Última revisión de 19:42 21 nov 2014



DWES TituloTema5.png



Icon preknowledge.gif

¿Qué son las sesiones?

  • Es otro método para hacer que variables estén disponibles en múltiples páginas
  • A diferencia de las cookies, las variables de sesión se almacenan en el servidor
  • Tienen un tiempo limitado de existencia.
  • Para identificar al usuario que generó las variables de sesión, el servidor genera una clave única que es enviada al navegador y almacenada en una cookie.
  • Luego, cada vez que el navegador solicita otra página al mismo sitio, envía esta cookie (clave única) con la cual el servidor identifica de qué navegador proviene la petición y puede rescatar de un archivo de texto las variables de sesión que se han creado.
  • Cuando han pasado 20 minutos sin peticiones por parte de un cliente (navegador) las variables de sesión son eliminadas automáticamente (se puede configurar el entorno de PHP para variar este tiempo).
  • Una variable de sesión es más segura que una cookie ya que se almacena en el servidor.
  • No tiene que estar enviándose continuamente como sucede con las cookies.
  • Cuando el navegador del cliente está configurado para desactivar las cookies las variables de sesión, tienen forma de funcionar (enviando la clave como parámetro en cada hipervínculo).
  • Desventaja: ocupa espacio en el servidor.



SSID de la sesión

  • Existen dos maneras de mantener el SSID de la sesión
  1. Utilizando cookies, tema ya visto.
  2. Propagando el SID en un parámetro de la URL. El SID se añade como una parte más de la URL, de la forma:
 http://www.misitioweb.com/tienda/listado.php&PHPSESSID=34534fg4ffg34ty
  • En el ejemplo anterior, el SID es el valor del parámetro PHPSESSID.
  • En php todas estas acciones se realizan de forma transparente para el programador, es decir, como desarrolladores podemos directamente utilizar las sesiones en php sin necesidad de tener que transmitir el SSID. Directemnte php nos ofrece supervariables y funciones para gestionarlo.

Configuración

  • Existen una serie de directivas para configurar las sesiones, que conviene conocer
  • Estas se pueden consultar viendo phpinfo(), y modificar en el fichero de configuración de php, php.ini
  • Para ver todas las directivas http://es.php.net/manual/es/session.configuration.php
session.use_cookies
Indica si se deben usar cookies (1) o propagación en la URL (0) para almacenar el SID.
session.use_only_cookies
Se debe activar (1) cuando utilizas cookies para almacenar los SID, y además no quieres que se reconozcan los SID que se puedan pasar como parte de la URL (este método se puede usar para usurpar el identificador de otro usuario).
session.save_handler
Se utiliza para indicar a PHP cómo debe almacenar los datos de la sesión del usuario. Existen cuatro opciones: en ficheros (files), en memoria (mm), en una base de datos SQLite (sqlite) o utilizando para ello funciones que debe definir el programador (user). El valor por defecto (files) funcionará sin problemas en la mayoría de los casos.
session.name
Determina el nombre de la cookie que se utilizará para guardar el SID. Su valor por defecto es PHPSESSID.
session.auto_start
Su valor por defecto es 0, y en este caso deberás usar la función session_start para gestionar el inicio de las sesiones. Si usas sesiones en el sitio web, puede ser buena idea cambiar su valor a 1 para que PHP active de forma automática el manejo de sesiones.
session.cookie_lifetime
Si utilizas la URL para propagar el SID, éste se perderá cuando cierres tu navegador. Sin embargo, si utilizas cookies, el SID se mantendrá mientras no se destruya la cookie. En su valor por defecto (0), las cookies se destruyen cuando se cierra el navegador. Si quieres que se mantenga el SID durante más tiempo, debes indicar en esta directiva ese tiempo en segundos.
session.gc_maxlifetime
Indica el tiempo en segundos que se debe mantener activa la sesión, aunque no haya ninguna actividad por parte del usuario. Su valor por defecto es 1440. Es decir, pasados 24 minutos desde la última actividad por parte del usuario, se cierra su sesión automáticamente.

Creando la sesión

  • En función de como esté configurado la directiva session.auto_start
  • Si esta activada, la sesión comienza automáticamente al conectarse a un sitio
  • Si no está activada la iniciaremos con la funcion session_start();


Icon casestudy.gif

Ejemplo

<? session_start();
if (!isset($_SESSION["cuenta_paginas"])){
    $_SESSION["cuenta_paginas"] = 1;
}else{
    $_SESSION["cuenta_paginas"]++;
}
?>
<html>
<head>
<title>Contar páginas vistas por un usuario en toda su sesión</title>
</head>
 
<body>
<?
echo "Desde que entraste has visto " . $_SESSION["cuenta_paginas"] . " páginas";
?>
<br>
<br>
<a href="otracuenta.php">Ver otra página</a>
</body>
</html>




Icon present.gif
Tip: Cuando se hace un cambio de estado (login, cambio de permisos, ...): regenerar id.
 session_regenerate_id()


  • Una vez creada la sesión podemos almacenar/consultar información de la misma consultando la variable superglobal $_SESSION

{{Ejemplo

<?php
// Iniciamos la sesión o recuperamos la anterior sesión existente
session_start();
// Comprobamos si la variable ya existe
if (isset($_SESSION['visitas']))
$_SESSION['visitas']++;
else
$_SESSION['visitas'] = 0;
?>

}}

  • Ahora almacenemos el instante en el que se produce cada visita
<?php
// Iniciamos la sesión o recuperamos la anterior sesión existente
session_start();
// En cada visita añadimos un valor al array "visitas"
$_SESSION['visitas'][] = mktime();
?>

Eliminando la sesion

  • se puede configurar para que de forma automática se eliminen los datos de una sesión pasados un determinado tiempo
  • También podemos actuar directamente sobre una sesión eliminando información
session_unset.
Elimina las variables almacenadas en la sesión actual, pero no elimina la información de la sesión del dispositivo de almacenamiento usado.
session_destroy.

Elimina completamente la información de la sesión del dispositivo de almacenamiento.


Icon activity.jpg

Actividad

  • Crea una página similar a la anterior usada en cookies,
  • Almacena en la sesión de usuario los instantes de todas sus últimas visitas.
  • Si es su primera visita, muestra un mensaje de bienvenida.
  • En caso contrario, muestra la fecha y hora de todas sus visitas anteriores. Añade un botón a la página que permita borrar el registro de visitas.
  • Utiliza también una variable de sesión para comprobar si el usuario se ha autentificado correctamente. De esta forma no hará falta comprobar las credenciales con la base de datos constantemente.


Propuesta de solución

<?php
// Si el usuario aún no se ha autentificado, pedimos las credenciales
if (!isset($_SERVER['PHP_AUTH_USER'])) {
    header('WWW-Authenticate: Basic realm="Contenido restringido"');
    header("HTTP/1.0 401 Unauthorized");
    exit;
}
// Vamos a guardar el usuario en una variable de sesión
// si no existe, aún no se ha autentificado
session_start();
if (!isset($_SESSION['usuario'])) {
// Conectamos a la base de datos
    $dwes = new mysqli("localhost", "root", "root", "dwes");
    $error = $dwes->connect_errno;
// Si se estableció la conexión
    if ($error == null) {
// Ejecutamos la consulta para comprobar si existe
// esa combinación de usuario y contraseña
        $sql = "SELECT usuario FROM usuarios
 WHERE usuario='${_SERVER['PHP_AUTH_USER']}' AND 
 contrasena=md5('${_SERVER['PHP_AUTH_PW']}')";
 
        $resultado = $dwes->query($sql);
// Si no existe, se vuelven a pedir las credenciales
        if ($resultado->num_rows == 0) {
            header('WWW-Authenticate: Basic realm="Contenido restringido"');
            header("HTTP/1.0 401 Unauthorized");
            exit;
        } else
            $_SESSION['usuario'] = $_SERVER['PHP_AUTH_USER'];
        $resultado->close();
        $dwes->close();
    }
}
// Si ya está autentificado
else {
// Comprobamos si se ha enviado el formulario de limpiar el registro
    if (isset($_POST['limpiar']))
        unset($_SESSION['visita']);
    else
        $_SESSION['visita'][] = time();
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "
    http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        <title>Ejemplo Tema 4: Cookies en autentificación HTTP</title><link href="dwes.css" rel="stylesheet" type="text/css">
    </head>
    <body>
        <?php
        if ($error == null) {
            echo "Nombre de usuario: " . $_SERVER['PHP_AUTH_USER'] . "<br />";
            echo "Hash de la contraseña: " . md5($_SERVER['PHP_AUTH_PW']) . "<br />";
            if (count($_SESSION['visita']) == 0)
                echo "Bienvenido. Esta es su primera visita.";
            else {
                date_default_timezone_set('Europe/Madrid');
                foreach ($_SESSION['visita'] as $v)
                    echo date("d/m/y \a \l\a\s H:i", $v) . "<br />";
                ?>
                <form id='vaciar' action='<?php echo $_SERVER['PHP_SELF']; ?>' method='post'>
                    <input type='submit' name='limpiar' value='Limpiar registro'/>
                </form>
                <?php
            }
        } else
            echo "Se ha producido el error $error.<br />";
        ?>
    </body>
</html>