Foros del Web » Programando para Internet » PHP »

Cookies incomibles (no se destruyen)

Estas en el tema de Cookies incomibles (no se destruyen) en el foro de PHP en Foros del Web. Buenos días gente, Tengo un problemilla con mi script de logout. Para mi login utilizo la variable $_SERVER y a partir de ello creo las ...
  #1 (permalink)  
Antiguo 15/07/2010, 03:17
 
Fecha de Ingreso: julio-2010
Mensajes: 7
Antigüedad: 14 años, 4 meses
Puntos: 0
Cookies incomibles (no se destruyen)

Buenos días gente,
Tengo un problemilla con mi script de logout. Para mi login utilizo la variable $_SERVER y a partir de ello creo las cookies y, por tanto, al hacer logout debo destruir $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] y las dos cookies que defino, 'login' y 'password'.

En definitiva, utilizo el siguiente script para el deslogueo:

Código PHP:
if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
    
$_SERVER['PHP_AUTH_USER'] = null;
    
$_SERVER['PHP_AUTH_PW'] = null;
    
//$_SERVER['HTTP_COOKIE'] = null;
}
if (isset(
$_COOKIE['login']) && isset($_COOKIE['password'])) {
        
//Destruimos las cookies
        
setcookie('login''x'time() - 3600);
        
setcookie('password''x'time() - 3600);
        
//setcookie('PHPSESSID', 'x', time() - 3600);
}
if (empty(
$_COOKIE['login']) && empty($_COOKIE['password']) && empty($_SERVER['PHP_AUTH_USER']) && empty($_SERVER['PHP_AUTH_PW'])) {
    echo 
'Se ha deslogueado correctamente';
    echo 
'<br />';
    echo 
'<button id="button" type="button" onclick="location.href=\'index.php\'">Volver al inicio</button>';
    exit();

Las dos líneas que tengo comentadas son pruebas a ver si conseguía hacer funcionar a la máquina, pero no ha sido posible. Lo más curioso es que borrando las cookies a través del navegador seguía sin funcionar el percal.

Por si sirve de algo, estoy probando en Google Chrome de Mac. Un saludo y muchas gracias.
  #2 (permalink)  
Antiguo 15/07/2010, 05:30
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 6 meses
Puntos: 1517
Respuesta: Cookies incomibles (no se destruyen)

Para autenticar usa sesiones. Te recomiendo que leas sobre el tema de las sesiones.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #3 (permalink)  
Antiguo 15/07/2010, 07:09
 
Fecha de Ingreso: febrero-2006
Mensajes: 134
Antigüedad: 18 años, 9 meses
Puntos: 10
Respuesta: Cookies incomibles (no se destruyen)

Los contenidos de $_SERVER son, al igual que $_ENV y al contrario que otras superglobales, de solo lectura, lo que significa que no puedes ir por ahí alegremente modificándolas.

PHP_AUTH_USER y PHP_AUTH_PW son cubiertas por el cliente en presencia de un campo WWW-Authenticate en la cabecera de la petición, al introducir sus credenciales, y el servidor web se las devuelve a tu aplicación.

¡Pero tú no puedes manualmente negar el hecho de que el usuario haya introducido esos datos! Porque eso sería mentir a la lógica ;)

En lugar de ello, si quieres seguir utilizando la autenticación HTTP como tu método de inicio de sesión, para cerrarla debes, además de utilizar cookies si quieres, cambiar la Realm de tu aplicación, invalidando las credenciales del navegador.

De todos modos, debes saber que el modo para que los navegadores que cumplan los estándares cierren tu sesión y se olviden de la cuenta abierta es cerrar la aplicación.

Pero si quieres no depender del usuario, y que vuelva a pedir credenciales, puedes hacer algo como:

Código PHP:

if($accion == 'login') {
  if(!isset(
$_SESSION['realmid'])) $_SESSION['realmid'] = mt_rand(500600);
  
header('WWW-Authenticate: basic realm="Mi aplicación web, tmp:'.$_SESSION['realmid']'"');
}
if(
$accion == 'logout') {
  
$_SESSION['realmid']++;

No sé si entiendes por donde van los tiros en mi código.. ;)
__________________
Si te ha gustado lo que he dicho, puedes darme algún punto de reputación, que no te cuesta nada ^_^.

Di no a los juicios de valor!
  #4 (permalink)  
Antiguo 15/07/2010, 07:26
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 6 meses
Puntos: 1517
Respuesta: Cookies incomibles (no se destruyen)

¿no es más fácil usar sesiones?
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #5 (permalink)  
Antiguo 15/07/2010, 07:40
 
Fecha de Ingreso: febrero-2006
Mensajes: 134
Antigüedad: 18 años, 9 meses
Puntos: 10
Respuesta: Cookies incomibles (no se destruyen)

Sesiones o no.. eso ya depende, porque las sesiones no son tan versátiles como parecen.

De todos modos, una recomendación, que acabo de volver a mirar el código: no es nada prudente almacenar una cookie 'login' y otra 'password', contenga como contenga al password (encriptado, espero).

Recuerda que las cookies viajan como texto plano por la web y, a menos que uses certificados SSL en todas las ocasiones, es un claro modo de atacar a usuarios.

Imagina que alguien obtiene esas cookies (porque, por ejemplo, se haya instalado un sniffer en un cibercafé); ¡cualquiera podría conectarse como ese usuario, incluso desde que el usuario hubiese cerrado sesión! (Porque podría regenerar la cookie)

Lo que está ahora más "de moda" es generar tokens únicos, y guardarlos en el servidor, de modo que esto sea lo que el navegador envía, y cuando el cliente cierre sesión el servidor destruye de su BBDD el token, de forma que cualquier otro usuario tampoco puede iniciar sesión con él.

También puedes, simplemente, usar sesiones (véase session_start()) u otros sistemas.

Pero esto ya es una recomendación que no venía a cuento de lo que preguntabas
__________________
Si te ha gustado lo que he dicho, puedes darme algún punto de reputación, que no te cuesta nada ^_^.

Di no a los juicios de valor!
  #6 (permalink)  
Antiguo 16/07/2010, 06:08
 
Fecha de Ingreso: julio-2010
Mensajes: 7
Antigüedad: 14 años, 4 meses
Puntos: 0
Respuesta: Cookies incomibles (no se destruyen)

Muchas gracias a los dos.

abimaelrc, no utilizo las sesiones más que nada porque ya las tengo "ocupadas" para otro tipo de funciones, y no me gusta ir mezclando, que así luego me pasa, que tengo un lío entre $_SESSION, $_SERVER, $_COOKIE, $_POST, $_GET,... pero bueno, en realidad me queda más claro, además de que me mola el efecto que da que te salga el pop up del navegador al hacer la validación mediante el servidor (si me decís cómo conseguir ese resultado con otros medios, soy todo oídos).

santhy, en primer lugar, la contraseña evidentemente encriptada y el login viajan en cookies cuyo nombre está también encriptado, gracias por el apunte ;)

Finalmente no te he hecho caso con el tema de usar un ID de sesión, ya que el navegador que usaba efectivamente sólo la cambiaba cuando lo cerraba, así que me he sacado de la manga una cookie con valores 0 o 1 que me dice si no he hecho logout o sí y, a partir de eso, mi función de login ya dilucida qué hacer.

Probablemente sea poco ortodoxo, pero funciona de la manera que yo quiero (con las pruebas que he hecho, que lo mismo mañana lo usa otro y peta), así que me vale.

Bueno, finalmente, aquí os dejo con el código:

Función de login
Código PHP:
function login() {
    
$loginkey md5('login');
    
$passwordkey md5('password');
    
    if (
$_COOKIE['session'] == && isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
        
mysql_connect('a ti te lo voy a decir''venga, sí, hombre...''y qué más') or die('Unable to connect MySQL server!');
        
mysql_select_db('va a ser que no') or die('Unable to select requested database!');
        
mysql_query("SET NAMES 'utf8'");
        
$query mysql_query("SELECT * FROM `users` WHERE `login` = '".$_SERVER['PHP_AUTH_USER']."'");
        
        if (
$row mysql_fetch_row($query)) {
            if (
$row[5] == md5($_SERVER['PHP_AUTH_PW'])) {
                
setcookie($loginkey$row[4], time() + 7776000); // 90 días dura la cookie
                
setcookie($passwordkey$row[5], time() + 7776000);
                
setcookie('session'1time() + 7776000);
                return 
$row;
            }
            else {
                echo 
'Contrase&ntilde;a incorrecta';
                echo 
'<br />';
                echo 
'<button id="button" type="button" onclick="location.href=\'index.php\'">Volver al inicio</button>';
                exit();
            }
        }
        else {
            echo 
'Usuario no existente en la base de datos';
            echo 
'<br />';
            echo 
'<button id="button" type="button" onclick="location.href=\'index.php\'">Volver al inicio</button>';
            exit();
        }
    
        
mysql_free_result($query);
        
mysql_close();
    }
    else if (isset(
$_COOKIE['session']) && isset($_COOKIE[$loginkey]) && isset($_COOKIE[$passwordkey])) {
        
mysql_connect('a ti te lo voy a decir''venga, sí, hombre...''y qué más') or die('Unable to connect MySQL server!');
        
mysql_select_db('va a ser que no') or die('Unable to select requested database!');
        
mysql_query("SET NAMES 'utf8'");
        
$query mysql_query("SELECT * FROM `users` WHERE `login` = '".$_COOKIE[$loginkey]."' AND `password` = '".$_COOKIE[$passwordkey]."'");
        
        if (
$row mysql_fetch_row($query)) {
            
setcookie($loginkey$row[4], time() + 7776000); // 90 días dura la cookie
            
setcookie($passwordkey$row[5], time() + 7776000);
            
setcookie('session'1time() + 7776000);
            return 
$row;
        }
        else {
            
//Destruimos las cookies.
            
setcookie($loginkey'x'time() - 3600);
            
setcookie($passwordkey'x'time() - 3600);
            
setcookie('session'1time() - 3600);
        }
    
        
mysql_free_result($query);
        
mysql_close();
    }
    else {
        
header('WWW-Authenticate: Basic realm="Mobail Apps SL"');
        if (
strpos($_SERVER['HTTP_USER_AGENT'], 'Chrome')) {
            if (
$_COOKIE['session'] == && $_COOKIE['chrome_control'] != 1) {
                
setcookie('session'1time() + 7776000);
                
setcookie('chrome_control'1time() + 7776000);
            }
            else {
                
setcookie('session'0time() + 7776000);
            } 
        }
        else if (
strpos($_SERVER['HTTP_USER_AGENT'], 'Safari')) {
            if (
$_COOKIE['session'] && $_COOKIE['safari_control'] != 1) {
                
setcookie('session'1time() + 7776000);
                
setcookie('safari_control'1time() + 7776000);
            }
            else {
                
setcookie('session'0time() + 7776000);
            }
        }
        else {
            
setcookie('session'0time() + 7776000);
        }
        
header('HTTP/1.1 401 Unauthorized');
        echo 
'Lo sentimos, pero no est&aacute; autorizado para ver esta p&aacute;gina';
        echo 
'<br />';
        echo 
'<button id="button" type="button" onclick="location.href=\'index.php\'">Volver al inicio</button>';
        exit();
    }

Función de logout
Código PHP:
$loginkey md5('login');
$passwordkey md5('password');

setcookie('session'1time() + 7776000);
if (isset(
$_COOKIE['chrome_control'])) {
    
setcookie('chrome_control'0time() - 3600);
}
if (isset(
$_COOKIE['safari_control'])) {
    
setcookie('safari_control'0time() - 3600);
}
setcookie($loginkey'x'time() - 3600);
setcookie($passwordkey'x'time() - 3600);

echo 
'Se ha deslogueado correctamente';
echo 
'<br />';
echo 
'<button id="button" type="button" onclick="location.href=\'index.php\'">Volver al inicio</button>';
exit(); 
Evidentemente, se admiten reclamaciones, quejas, insultos, improperios y demás. Un saludo.

PD Edit 1: si antes lo digo... los códigos que tenía antes colgados no funcionaban muy para allá. Finalmente lo he solucionado, aunque he tenido que verme forzado a meter parches para Safari y Chrome, pero si funciona...

Última edición por Javi_Portillo; 20/07/2010 a las 04:44 Razón: Corregir código

Etiquetas: cookies
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 12:16.