entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

3votos

CERRAR SESSIONES PHP

Buenas a todos, espero puedan ayudarme con esta inquietud, estoy desarrollando un proyecto para una empresa y necesito tener un registro de las sesiones de usuario con su hora de entrada y hora de salida, a la hora de la entrada no tengo ningún problema, el problema surge cuando el usuario cierra sesión, y este simplemente no le da al botón salir del sistema entonces este no me guarda la hora de salida, Ya tengo que cada cierto tiempo se verifique la inactividad del usuario para el cierre automático, pero si este cierra el navegador no se hace esta verificación, ¿Alguien tiene alguna idea para guiarme?. Pongo el código que tengo hasta ahora.

validar.php

/*se inicia la session*/
            session_name("prueba");
            session_start();
            //cambiamos la duración a la cookie de la sesión 
            session_set_cookie_params(0, "/", $HTTP_SERVER_VARS["HTTP_HOST"], 0);
            $_SESSION["ultimoAcceso"]= date("Y-m-d H:i:s"); 

Este el codigo que inicia la sesion de usuario y toma la hora y fecha actual de esta luego de que sea correcta la validación de mi usuario

sesion.php

session_name("prueba");
session_start();

//cambiamos la duración a la cookie de la sesión 
session_set_cookie_params(0, "/", $HTTP_SERVER_VARS["HTTP_HOST"], 0); 
//si la session no esta iniciada lo regresa a la pagina principal
    if($verificar!="registrarse") 
    {
        echo "<script>window.parent.location.href='salir.php';</script>";
    }
     else {  
    //sino, calculamos el tiempo transcurrido 
    $fechaGuardada = $_SESSION["ultimoAcceso"]; 
    $ahora = date("Y-m-d H:i:s"); 
    $tiempo_transcurrido = $ahora-$fechaGuardada; 

    //comparamos el tiempo transcurrido 
     if($tiempo_transcurrido >= 900) { 
     //900 si pasaron 30 minutos o más 
      session_destroy(); // destruyo la sesión 
      echo "<script>window.parent.location.href='salir.php';</script>"; //envío al usuario a la pag. de autenticación 
      //sino, actualizo la fecha de la sesión 
    }else { 
    $_SESSION["ultimoAcceso"] = $ahora; 
   } 
}

aqui verifico la inactividad y actualizo la hora y fecha de ingreso

salir.php

include('conectarse.php');//conexion con la base de datos
include('session.php');//incluir el archivo de sesión

session_name("prueba"); // nombre de la sesión iniciada
session_start(); //iniciar la sesión

$hora=date('H:i:s');//se toma la hora actual
$ced=$_SESSION['cedula'];
$sql=pg_query("SELECT * FROM historial_session where cd_p='$ced' ORDER BY id_hist DESC LIMIT 1");//se hace la consulta para que tome el ultimo registro de ese usuario
$array=pg_fetch_array($sql);
$id=$array['id_hist'];

$sql2="UPDATE historial_session SET hora_salid='$hora' WHERE id_hist='$id'";//se actualiza la hora de salida
$resultado2=pg_exec($sql2);

unset($_SESSION['prueba']);
// destruye la sesión
  session_destroy();
  header("Location: ../");//se manda a la pagina de inicio
  exit;

aqui cierro la sesion y guardo la hora de salida de este
no se cual es el problema :l

3 Respuestas

4votos

Leonardo-Tadei Puntos227320

Hola @doblea_pg,

en general, siempre hay un escenario en que el usuario puede abandonar el sitio sin darle a "salir". A veces es cerrando el navegador, a veces será cerrando la sesión en la PC, a veces será apagando el equipo y a veces será por un corte de energía o agotamiento de baterías.

Dado que no es posbible detectar todas las salidas posibles, lo que se estila es no hacerlo ;-)

Una mejor estrategia es que, cuando el usuario vuelva a entrar, verificar si hora_salid tiene un dato o no. En caso de no tenerlo, se lo ponés o calculás al mismo tiempo que se inicia la nueva sesión.

Para hacer esto, en los datos de la sesión te hace falta 3 valores: hora_ingreso, hora_uptime y hora_salida.

En el script que inicia la sesión, creás un nuevo registro y le asignás la hora de ingreso. En el script que mantiene la sesión (que debería estar al principio de cada script del sitio) actualizaás el valor de la hora de uptime. Al cerrar la sesión, asigmás el valor de la hora de salida.

En el caso de que un nuevo login encuentre que el login anterior no tiene escrita la hora de salida, se la calculás en base a la última hora de uptime guardada. Para tu caso, dado que el tiempo de sesión es de 30 minutos, podrías poner como hora de salida el uptime + 15 minutos, que sería tu promedio de incertidumbre; también podrías penalizar al usuario que no cerró la sesión sumándole menos tiempo o nada.

Esta estrategia también podrías usarla en un script que corra automáticamente a la noche, y cierre todas las sesiones abiertas durante el día.

Aprovecho para hacerte una observación: siempre redirigí al usuario para sacarlo del sistema con un header("Location: ") y no desde JavaScript, ya que el usuario puede no soportar o deshabilitar el JavaScript y ver el resto de la página, si existiese, o quedarse imposibilitado de salir.

Saludos cordiales!

2votos

doblea_pg comentado

Muchas gracias!!! :) no lo había visto desde ese punto de vista pero si tienes mucha razón, así lo hice y pude solucionar ese problema para cuando el usuario inicie sesión nuevamente. Ya si ese usuario no inicia sesión de nuevo quedaría así.

O ¿Crees que seria factible hacer un bucle donde con cualquier nuevo inicio de sesión me busque los registros que tengan la Hora de salida NULL y me sustituya esos valores por la hora de uptime?, Consulto esto por que no se si seria algo factible.

2votos

Leonardo-Tadei comentado

Hola @doblea_pg,

Es cierto que si el usuario no inicia sesión nunca más, te queda ese horario de salida vacío.

Chequear esto en cada inicio de sesión de cualquier usuario, me parece demasiado costoso en recursos si tenés muchos usuarios, pero es posible.

Lo que yo te sugería para solucionar esto es ejecutar un script que haga los cierres de todos, pero que se ejecuta vía una tarea CRON en algún horario de poco uso del servidor, por ejemplo a las 3am.

El script PHP puede ser CGI y llamado como un comando, y ser una "página web" y le hacés la llamada con wget o similar. Lo único a tener en cuenta sería que este script al no ser interactivo, no tiene que pedir un usuario logueado, pero dado que tiene una función limitada, no debería ser problema.

Saludos cordiales y me alegra que te haya servido la idea!

3votos

morgooth Puntos2340

Mira este código, así puedes detectar cuando salga del sitio o recargue la pagina.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
    <title></title>
<script language="JavaScript" type="text/javascript">

    var bPreguntar = true;

    window.onbeforeunload = preguntarAntesDeSalir;

    function preguntarAntesDeSalir()
    {
      if (bPreguntar)
        return "¿Seguro que quieres salir?";
    }
</script>
</head>
<body>
<h1>Ejemplo de abandono de página</h1>
<p>Por defecto preguntará hasta que pulses el botón de "No preguntar"</p>
<input type="button" value="Preguntar" onclick="bPreguntar = true;" >
&nbsp;&nbsp;
<input type="button" value="No preguntar" onclick="bPreguntar = false;" >
<br/><br/>
<a href="http://www.google.cl">Ir a otra página</a>
</body>
</html>

2votos

doblea_pg comentado

Si, antes de realizar mi pregunta investigue alguna forma de hacerlo, el problema con ese código es que se ejecutara al recargar cada pagina y pues seria tedioso estar navegando en un sistema y que a cada raro te saliera ese ventanita de mensaje... :l por eso no lo aplique y no he encontrado alguna otra forma de hacerlo... Por que no se si seria darle solo 3 minutos de inactividad al usuario como en los bancos, porque como esta ahora la hora de salida que debo registrar en la base de datos seria NULL y no es el punto para llevar un control de sesiones de un sistema :l ¿O alguna otra sugerencia?

3votos

angelAparicio Puntos2810

Una posibilidad (no muy eficiente, la verdad), sería usar una llamada ajax para grabar en base de datos la hora de conexión actual del usuario.

Si vas grabando esta hora cada minuto y el usuario cierra el navegador sin cerrar la sesión, tendrás guardado el último momento de conexión, con un error máximo de un minuto.

Como he dicho, esto no es muy eficiente, pues estarás haciendo un montón de inserciones en la base de datos. Pero dependiendo del escenario (pocos usuarios, p. ej.), te puede valer.

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta