PHP - USUARIO SE MANTIENE CONECTADO SI CIERRO NAVEGADOR

 
Vista:
sin imagen de perfil
Val: 79
Ha mantenido su posición en PHP (en relación al último mes)
Gráfica de PHP

USUARIO SE MANTIENE CONECTADO SI CIERRO NAVEGADOR

Publicado por Jonathan (40 intervenciones) el 29/08/2020 21:32:36
Tengo una tabla usuarios con sus respectivas columnas, una de ellas almacena el id de sesión para verificar si el usuario esta o no conectado.

Tengo una función Ajax que me muestra los usuarios conectados y se actualiza cada cierto tiempo de forma automática. Hasta ahí todo sin ningún problema.

En el archivo login.php inicio la sesión obteniendo el id de sesión anterior para destruirlo y de esta forma se cierra la sesión del usuario si es que esta iniciada en otro navegador o equipo. Luego actualizo la base de datos y guardo el nuevo id de sesión.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
include 'conexion.php';
$con = new Conexion();
session_set_save_handler(new \SessionHandler());
session_start();
$error='';
if (isset($_POST['submit'])) {
    if (empty($_POST['usuario']) || empty($_POST['clave'])) {
        $error = "Ingrese un usuario y contraseña validos";
    }else{
        $usuario = $_POST['usuario'];
		$clave = base64_encode($_POST['clave']);
        $comprobar = "SELECT usuario,clave,nombre,apellido,genero,rol,sid FROM usuarios WHERE usuario = '$usuario' AND clave='$clave'";
        if (($con->numerofilas2($comprobar)) == 1){
			$query_comprobar = mysqli_query($con->conexion,$comprobar);
			$fila = mysqli_fetch_assoc($query_comprobar);
			date_default_timezone_set("America/Santiago");
			$_SESSION['fecha'] = date("Y-m-d G:i:s");
			$_SESSION['usuario'] = $fila['usuario'];
			$_SESSION['nombre'] = $fila['nombre'];
			$_SESSION['apellido'] = $fila['apellido'];
			$_SESSION['genero'] = $fila['genero'];
			$_SESSION['rol'] = $fila['rol'];
			$_SESSION['sesion-start'] = time();
			$_SESSION['sesion-expire'] = $_SESSION['sesion-start'] + (15 * 60);
			$sessionID = $fila['sid'];
			$insertar = mysqli_query($con->conexion,"INSERT INTO historial_login VALUES(null,'".$_SESSION['usuario']."','".$_SESSION['nombre']."','".$_SESSION['apellido']."','".$_SESSION['fecha']."')");
			(new \SessionHandler())->destroy($sessionID);
			$id = session_id();
			$sid = mysqli_query($con->conexion,"UPDATE usuarios SET sid = '$id' WHERE usuario = '".$_SESSION['usuario']."'");
            header("location: ../inicio.php");
        }else{
            $error = "Usuario o contarseña incorrectos";
        }
    }
}
?>

En el archivo sesion.php verifico cada vez que se abre una pagina si no a pasado el tiempo de expiracion, extiendo la sesión de lo contrario expira y se cierra, actualizando la tabla usuarios dejando el campo id de sesión vació.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php
setlocale(LC_ALL,"es_ES");
include("conexion.php");
$con = new Conexion();
session_start();
if(!isset($_SESSION['usuario'])){
	mysqli_close($con->conexion);
	header('Location: '.$raiz);
}else{
	$ahora = time();
	if($ahora > $_SESSION['sesion-expire']){
		$liberar = mysqli_query($con->conexion,"UPDATE usuarios SET sid = NULL WHERE usuario = '".$_SESSION['usuario']."'");
		unset($_SESSION['fecha']);
		unset($_SESSION['usuario']);
		unset($_SESSION['nombre']);
		unset($_SESSION['apellido']);
		unset($_SESSION['genero']);
		unset($_SESSION['rol']);
		unset($_SESSION['sesion-start']);
		unset($_SESSION['sesion-expire']);
		mysqli_close($con->conexion);
		session_regenerate_id();
		session_destroy();
		header('Location: '.$raiz);
	}else{
		$_SESSION['sesion-expire'] = time() + (15 * 60);
		$host = $_SERVER["HTTP_HOST"];
		$url = substr($_SERVER["REQUEST_URI"],21,-4);
		$query = "SELECT * FROM permisos WHERE rol = '".$_SESSION['rol']."'";
		$permisos = $con->obtenerdatos($query);
		$filas = $con->numerofilas2($query);
		for($i=0,$filas;$i<$filas;$i++){
			$ruta = $permisos[$i]['ruta'];
			$permiso = $permisos[$i]['permiso'];
			if($ruta == $url and $permiso == 0){
				header('Location: '.$raiz.'logica/acceso_denegado.php');
			}
		}
	}
}
 
?>

Lo mismo en el archivo cerrarsesion.php, Libero las variables, destruyo la sesion actual y vuelvo a dejar el campo sid en vació.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
include 'conexion.php';
$con = new Conexion();
session_start();
$liberar = mysqli_query($con->conexion,"UPDATE usuarios SET sid = NULL WHERE usuario = '".$_SESSION['usuario']."'");
unset($_SESSION['fecha']);
unset($_SESSION['usuario']);
unset($_SESSION['nombre']);
unset($_SESSION['apellido']);
unset($_SESSION['genero']);
unset($_SESSION['rol']);
unset($_SESSION['sesion-start']);
unset($_SESSION['sesion-expire']);
mysqli_close($con->conexion);
session_regenerate_id();
session_destroy();
header("Location: ../");
exit;
?>

El problema viene cuando en ciertos navegadores la sesión se cierra al cerrar el navegador por completo o la cesión es cerrada por borrar el historial o cookies del navegador, lo cual no me estaría actualizando la tabla usuarios volviendo el campo sid a vacio. Por lo cual el usuario aun figura como conectado en el sistema, a pesar de que no existe una sesión iniciada.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de joel
Val: 3.828
Oro
Ha mantenido su posición en PHP (en relación al último mes)
Gráfica de PHP

USUARIO SE MANTIENE CONECTADO SI CIERRO NAVEGADOR

Publicado por joel (1269 intervenciones) el 30/08/2020 09:07:20
Hola Jonathan, este problema es común... yo te voy a indicar la solución que hemos optado nosotros en este tipo de casos.

Al no saber nunca si un usuario se ha ido o no, lo que hacemos es que a cada pagina que va el usuario se actualiza la tabla "usuarios" (en tu caso) guardando siempre la última hora en que el usuario visito una pagina.
De esta manera, siempre tenemos los usuarios activos, y la ultima hora en la que visito alguna de nuestras paginas.

Por detras, tenemos un proceso que se ejecuta cada 5 minutos, que pone a NULL el campo "sid" a todos los registros que lleven mas de 10 minutos sin actualizar la fecha en la tabla "usuarios".

De esta manera, siempre tienes todos los usuarios activos de los últimos 10 minutos.

El valor de 10 minutos lo puedes cambiar por el tiempo que creas necesario.


Espero que te sirva.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar