Como ejercicio para la clase, estoy creando una clase que administra las sesiones de usuario.
Los detalles de la sesión se almacenan en una base de datos y también hay una variable $_SESSION[user_id]
para llevar entre páginas.
La idea es que sería difícil para un atacante robar la cookie Y la dirección IP Y el agente de usuario Y mantener la sesión actualizada, ya que puse un límite de 15 minutos.
Cuando el usuario inicia sesión, se crea el objeto de la base de datos y se verifica su existencia en cada página visitada.
<?php
//Recojo parametros de formulario de logeo
$username = $_POST['username'];
$password = $_POST['password'];
//abro conexion base de datos
$mysqli = new mysqli("localhost", "root", "unir_2014", "wordpress");
if ($mysqli->connect_errno) {
printf("La conexion ha fallado! El servidor responde: %s\n", $mysqli->connect_error);
exit();
}
//----------------------------------------------------------------------------------------//
//----------------------------------------------------------------------------------------// //EXPIRAR
$comienzo = time(); // Momento al logearse
// Le damos un tiempo de expiracion de 1 minuto
$expirar = $comienzo + (15 * 60);
//----------------------------------------------------------------------------------------// //IP ADDRESS
if (isset($_SERVER)) {
if (isset($_SERVER["HTTP_X_FORWARDED_FOR"]) && ip2long($_SERVER["HTTP_X_FORWARDED_FOR"]) !== false) {
$ipadres = $_SERVER["HTTP_X_FORWARDED_FOR"];
} elseif (isset($_SERVER["HTTP_CLIENT_IP"]) && ip2long($_SERVER["HTTP_CLIENT_IP"]) !== false) {
$ipadres = $_SERVER["HTTP_CLIENT_IP"];
} else {
$ipadres = $_SERVER["REMOTE_ADDR"];
}
} else {
if (getenv('HTTP_X_FORWARDED_FOR') && ip2long(getenv('HTTP_X_FORWARDED_FOR')) !== false) {
$ipadres = getenv('HTTP_X_FORWARDED_FOR');
} elseif (getenv('HTTP_CLIENT_IP') && ip2long(getenv('HTTP_CLIENT_IP')) !== false) {
$ipadres = getenv('HTTP_CLIENT_IP');
} else {
$ipadres = getenv('REMOTE_ADDR');
}
}
//----------------------------------------------------------------------------------------// $version_cliente = $_SERVER['HTTP_USER_AGENT'];
//----------------------------------------------------------------------------------------//$query = "SELECT * FROM sesiones WHERE name ='" .$username."'";
if ($result = $mysqli->query($query)) {
while($row = mysqli_fetch_array($result)) {
$salt = $row['salt'];
$passcheck = $row['password'];
$id_usuario = $row['id_usuario'];
$passwordin = md5($password.$salt);
$direccion_ip = $ipadres;
}
//compruebo si la contraseña coincide con el hash almacenado en la base de datos
if( $passcheck === $passwordin){
echo '<script> window.location = "privatecontent.php" </script>';
//if the user has javascript
$url = 'privatecontent.php';
echo '<META HTTP-EQUIV=Refresh CONTENT="0; URL='.$url.'">';
//if the user doesnt have javascript*
//----------------------------------------------------------------------------------------// //INTRODUCIMOS OBJETO SESSION EN LA BASE DE DATOS
//mysqli_query($connection, "INSERT INTO 'wordpress'.'session_log' ('id_sesion', 'id_usuario', 'direccion_ip', 'version_cliente', 'expirar') VALUES ('', '".$id_usuario."', '".$direccion_ip."', '".$version_cliente."', '".$expirar."');");
mysqli_query($mysqli, "INSERT INTO 'wordpress'.'session_log' ('id_sesion', 'id_usuario', 'direccion_ip', 'version_cliente', 'expirar') VALUES ('', '".$id_usuario."', '".$direccion_ip."', '".$version_cliente."', '".$expirar."');");
//la variable de sesion solo almacena la id de usuario en uso, para asociarlo a la sesion de la base de datos
session_start();
$_SESSION['user_id'] = $id_usuario;
}
}
else{
echo '<div id="wrong" class="wrong"> "Nombre de usuario o contraseña incorrectos! <br>';
echo "Haz click<a href='FORMULARIO DE REGISTRO!!!'>aqui</a> para registrarte...</div>";
}
Ese sería el administrador de inicio de sesión, ahora, la clase check_login:
<?php
// TODAS LAS PAGINAS DEBEN INCLUIR ESTE ARCHIVO!
//abro conexion base de datos
$mysqli = new mysqli("localhost", "root", "unir_2014", "wordpress");
if ($mysqli->connect_errno) {
printf("La conexion ha fallado! El servidor responde: %s\n", $mysqli->connect_error);
exit();
}
//buscamos el id del usuario activo.
//recibimo de $_SESSION (o sea la cookie del cliente) solo el id del usuario. que usuario dice ser
//si la cookie ha sido robada, lo mas probable es que la ip y el user agent hayan cambiado, asi que la session FALLARA
//robar una cookie antigua tampoco ayudara, pues solo duran 15 minutos
session_start();
$id_usuario = $_SESSION['user_id'];
//busco en la tabla SESIONES si existe un numbre de usuario como ese
$query = "SELECT * FROM session_log WHERE id_usuario ='".$id_usuario."'";
//si existe, saco sus datos
if ($result = $mysqli->query($query)) {
while($row = mysqli_fetch_array($result)) {
$ip_check = $row['direccion_ip'];
$expirar = $row['expirar'];
$cliente_check = $row['version_cliente'];
$id_sesion = $row['id_sesion'];
}
}
//comprobamos que el usuario esta logeado, tiene buen user_agent, la misma direccion ip y no se ha pasado de tiempo
//COMPROBAR SI LA SESION HA EXPIRADO
$now = time();
if ($now > $expirar) {
$url = 'NO_SESSION.php';
echo '<script> window.location = "'.$url.'" </script>';
echo '<META HTTP-EQUIV=Refresh CONTENT="0; URL='.$url.'">';
}
//COMPROBAR QUE VIENE DE LA MISMA IP
if (isset($_SERVER)) {
if (isset($_SERVER["HTTP_X_FORWARDED_FOR"]) && ip2long($_SERVER["HTTP_X_FORWARDED_FOR"]) !== false) {
$ipadres = $_SERVER["HTTP_X_FORWARDED_FOR"];
} elseif (isset($_SERVER["HTTP_CLIENT_IP"]) && ip2long($_SERVER["HTTP_CLIENT_IP"]) !== false) {
$ipadres = $_SERVER["HTTP_CLIENT_IP"];
} else {
$ipadres = $_SERVER["REMOTE_ADDR"];
}
} else {
if (getenv('HTTP_X_FORWARDED_FOR') && ip2long(getenv('HTTP_X_FORWARDED_FOR')) !== false) {
$ipadres = getenv('HTTP_X_FORWARDED_FOR');
} elseif (getenv('HTTP_CLIENT_IP') && ip2long(getenv('HTTP_CLIENT_IP')) !== false) {
$ipadres = getenv('HTTP_CLIENT_IP');
} else {
$ipadres = getenv('REMOTE_ADDR');
}
}
if ($ip_check !== $ipadres){
$url = 'NO_SESSION.php';
echo '<script> window.location = "'.$url.'" </script>';
echo '<META HTTP-EQUIV=Refresh CONTENT="0; URL='.$url.'">';
}
//COMPROBAR QUE TIENE EL MISMO USER AGENT
$version_cliente = $_SERVER['HTTP_USER_AGENT'];
if ($cliente_check != $version_cliente){
$url = 'NO_SESSION.php';
echo '<script> window.location = "'.$url.'" </script>';
echo '<META HTTP-EQUIV=Refresh CONTENT="0; URL='.$url.'">';
}
//si ninguno de estos controles falla, llego hasta aqui
//significa que el usuario ha visitado una pagina nueva y sigue con la misma session, asi que debo
//actualizar el campo "expirar" para que la session dure mas
$new_expirar = time() + (15 * 60);
mysqli_query($mysqli, "UPDATE 'wordpress'.'session_log' SET 'expirar' = '".$new_expirar."' WHERE 'session_log'.'id_sesion' =$id_sesion;");