Autenticación HTTP cerrar sesión a través de PHP


¿Cuál es la forma correcta de cerrar sesión en la carpeta protegida de autenticación HTTP?

Hay soluciones que pueden lograr esto, pero son potencialmente peligrosas porque pueden tener errores o no funcionan en ciertas situaciones / navegadores. Es por eso que estoy buscando una solución correcta y limpia.

Author: bignose, 2009-01-16

17 answers

Mu. No existe una forma correcta, ni siquiera una que sea consistente en todos los navegadores.

Este es un problema que viene de la especificación HTTP (sección 15.6):

Los clientes HTTP existentes y los agentes de usuario normalmente conservan la autenticación información indefinidamente. HTTP/1.1. no proporciona un método para un servidor para dirigir a los clientes a descartar estas credenciales almacenadas en caché.

Por otra parte, la sección 10.4.2 dice:

Si la solicitud ya incluía credenciales de autorización, entonces el 401 response indicates that authorization has been refused for those credencial. Si la respuesta 401 contiene el mismo desafío que el respuesta previa, y el agente de usuario ya ha intentado autenticación al menos una vez, entonces el usuario DEBE presentar el entidad que se dio en la respuesta, ya que esa entidad podría incluya información diagnóstica relevante.

En otras palabras, puede ser capaz de mostrar el cuadro de inicio de sesión de nuevo (como @Karsten dice), pero el navegador no tiene que cumplir con su solicitud - así que no dependa demasiado de esta (mal)característica.

 102
Author: Piskvor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:30

Método que funciona muy bien en Safari. También funciona en Firefox y Opera, pero con una advertencia.

Location: http://[email protected]/

Esto le dice al navegador que abra la URL con un nuevo nombre de usuario, anulando el anterior.

 57
Author: Kornel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-21 21:44:52

La respuesta simple es que no puede cerrar sesión de manera confiable en la autenticación http.

La respuesta larga:
Http-auth (como el resto de la especificación HTTP) está destinado a ser sin estado. Así que estar "conectado " o" desconectado " no es realmente un concepto que tenga sentido. La mejor manera de verlo es preguntar, para cada solicitud HTTP (y recuerde que una carga de página suele ser múltiples solicitudes), "¿se le permite hacer lo que está solicitando?". El servidor ve cada solicitud como nueva y no relacionada con ninguna anterior peticiones.

Los navegadores han optado por recordar las credenciales que les dices en el primer 401, y volver a enviarlas sin el permiso explícito del usuario en las solicitudes posteriores. Este es un intento de dar al usuario la "conectado/desconectado" modelo que esperar, pero es puramente un parche. Es el navegador el que simula esta persistencia de estado. El servidor web es completamente inconsciente de ello.

Así que "cerrar sesión", en el contexto de http-auth es puramente una simulación proporcionado por el navegador, y por lo tanto fuera de la autoridad del servidor.

Sí, hay kludges. Pero rompen la tranquilidad (si eso es de valor para ti) y no son confiables.

Si necesita absolutamente un modelo de inicio/cierre de sesión para la autenticación de su sitio, la mejor opción es una cookie de seguimiento, con la persistencia del estado almacenada en el servidor de alguna manera (mysql, sqlite, flatfile, etc.). Esto requerirá que todas las solicitudes sean evaluadas, por ejemplo, con PHP.

 43
Author: Jonathan Hanson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-11 13:37:36

Solución alternativa

Puedes hacer esto usando Javascript:

<html><head>
<script type="text/javascript">
function logout() {
    var xmlhttp;
    if (window.XMLHttpRequest) {
          xmlhttp = new XMLHttpRequest();
    }
    // code for IE
    else if (window.ActiveXObject) {
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    if (window.ActiveXObject) {
      // IE clear HTTP Authentication
      document.execCommand("ClearAuthenticationCache");
      window.location.href='/where/to/redirect';
    } else {
        xmlhttp.open("GET", '/path/that/will/return/200/OK', true, "logout", "logout");
        xmlhttp.send("");
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4) {window.location.href='/where/to/redirect';}
        }


    }


    return false;
}
</script>
</head>
<body>
<a href="#" onclick="logout();">Log out</a>
</body>
</html>

Lo que se hace arriba es:

  • Para IE - solo borra la caché de autenticación y redirige a algún lugar

  • Para otros navegadores - enviar un XMLHttpRequest detrás de escena con 'logout' nombre de usuario y contraseña. Necesitamos enviarlo a alguna ruta que devolverá 200 OK a esa solicitud (es decir, no debería requerir autenticación HTTP).

Sustitúyase '/where/to/redirect' por alguna ruta a la que redirigir después de cerrar sesión y reemplazar '/path/that/will/return/200/OK' con alguna ruta en su sitio que devolverá 200 OK.

 24
Author: Anton Mochalin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-12 20:12:53

Solución (no es un limpio, agradable (o incluso de trabajo! ver comentarios) solución):

Desactive sus credenciales una vez.

Puede mover su lógica de autenticación HTTP a PHP enviando los encabezados apropiados (si no ha iniciado sesión):

Header('WWW-Authenticate: Basic realm="protected area"');
Header('HTTP/1.0 401 Unauthorized');

Y analizando la entrada con:

$_SERVER['PHP_AUTH_USER'] // httpauth-user
$_SERVER['PHP_AUTH_PW']   // httpauth-password

Así que deshabilitar sus credenciales una vez debería ser trivial.

 13
Author: Karsten,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-18 11:58:55

Cerrar sesión desde HTTP Basic Auth en dos pasos

Digamos que tengo un dominio de autenticación Básica HTTP llamado "Protegido por contraseña", y Bob está conectado. Para cerrar sesión hago 2 solicitudes AJAX:

  1. Script de acceso /logout_step1. Agrega un usuario temporal aleatorio a .htusers y responde con su nombre de usuario y contraseña.
  2. Access script /logout_step2 autenticado con el login y la contraseña del usuario temporal. El script elimina el usuario temporal y añade este encabezado en el respuesta: WWW-Authenticate: Basic realm="Password protected"

En este punto el navegador olvidó las credenciales de Bob.

 7
Author: Vlad GURDIGA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-23 21:04:29

Mi solución al problema es la siguiente. Usted puede encontrar la función http_digest_parse , $realm y $users en el segundo ejemplo de esta página: http://php.net/manual/en/features.http-auth.php.

session_start();

function LogOut() {
  session_destroy();
  session_unset($_SESSION['session_id']);
  session_unset($_SESSION['logged']);

  header("Location: /", TRUE, 301);   
}

function Login(){

  global $realm;

  if (empty($_SESSION['session_id'])) {
    session_regenerate_id();
    $_SESSION['session_id'] = session_id();
  }

  if (!IsAuthenticated()) {  
    header('HTTP/1.1 401 Unauthorized');
    header('WWW-Authenticate: Digest realm="'.$realm.
   '",qop="auth",nonce="'.$_SESSION['session_id'].'",opaque="'.md5($realm).'"');
    $_SESSION['logged'] = False;
    die('Access denied.');
  }
  $_SESSION['logged'] = True;  
}

function IsAuthenticated(){
  global $realm;
  global $users;


  if  (empty($_SERVER['PHP_AUTH_DIGEST']))
      return False;

  // check PHP_AUTH_DIGEST
  if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) ||
     !isset($users[$data['username']]))
     return False;// invalid username


  $A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]);
  $A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);

  // Give session id instead of data['nonce']
  $valid_response =   md5($A1.':'.$_SESSION['session_id'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);

  if ($data['response'] != $valid_response)
    return False;

  return True;
}
 6
Author: Pie86,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-01 23:38:59

Normalmente, una vez que un navegador le ha pedido al usuario credenciales y las ha suministrado a un sitio web en particular, continuará haciéndolo sin más solicitudes. A diferencia de las diversas formas en que puede borrar las cookies en el lado del cliente, no conozco una forma similar de pedirle al navegador que olvide sus credenciales de autenticación suministradas.

 4
Author: Greg Hewgill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-16 08:01:49

Trac - por defecto - también usa autenticación HTTP. Cerrar sesión no funciona y no se puede arreglar:

  • Este es un problema con el esquema de autenticación HTTP en sí, y no hay nada que podamos hacer en Trac para solucionarlo correctamente.
  • Actualmente no hay una solución (JavaScript u otra) que funcione con todos los navegadores principales.

Desde: http://trac.edgewall.org/ticket/791#comment:103

Parece que no hay respuesta de trabajo a la pregunta, ese problema se ha reportado hace siete años y tiene perfecto sentido: HTTP es apátrida. Una solicitud se realiza con credenciales de autenticación o no. Pero eso es cuestión del cliente que envía la solicitud, no del servidor que la recibe. El servidor solo puede decir si un URI de solicitud necesita autorización o no.

 2
Author: hakre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-06 18:05:28

Necesitaba reiniciar .autorización htaccess así que usé esto:

<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
    header('WWW-Authenticate: Basic realm="My Realm"');
    header('HTTP/1.0 401 Unauthorized');
    echo 'Text to send if user hits Cancel button';
    exit;
}
?>

Lo encontré aquí : http://php.net/manual/en/features.http-auth.php

Vaya figura.

Una serie de soluciones residen en esa página e incluso señala en la parte inferior: Lynx, no borra la autenticación como otros navegadores;)

Lo probé en mis navegadores instalados y una vez cerrado, cada navegador parece que constantemente requiere reauth en la reentrada.

 2
Author: Dooley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-07 07:00:52

Esta podría no ser la solución que se buscó, pero lo resolví así. tengo 2 scripts para el proceso de cierre de sesión.

Cerrar sesión.php

<?php
header("Location: http://[email protected]/log.php");
?>

Log.php

<?php
header("location: https://google.com");
?>

De esta manera no recibo una advertencia y mi sesión se termina

 2
Author: Kevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-02 19:16:22

AFAIK, no hay una forma clara de implementar una función "logout" cuando se utiliza la autenticación htaccess (es decir, basada en HTTP).

Esto se debe a que dicha autenticación utiliza el código de error HTTP '401' para indicar al navegador que se requieren credenciales, momento en el que el navegador solicita al usuario los detalles. A partir de entonces, hasta que el navegador se cierre, siempre enviará las credenciales sin necesidad de solicitar más información.

 1
Author: Alnitak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-16 08:03:37

La mejor solución que he encontrado hasta ahora es (es una especie de pseudo-código, el $isLoggedIn es pseudo variable para http auth):

En el momento de "cerrar sesión" simplemente almacene información en la sesión diciendo que el usuario realmente ha cerrado sesión.

function logout()
{
  //$isLoggedIn = false; //This does not work (point of this question)
  $_SESSION['logout'] = true;
}

En el lugar donde compruebo la autenticación expando la condición:

function isLoggedIn()
{
  return $isLoggedIn && !$_SESSION['logout'];
}

La sesión está algo vinculada al estado de la autenticación http, por lo que el usuario permanece desconectado mientras mantenga abierto el navegador y la autenticación http persiste en el navegador.

 1
Author: Josef Sábl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-30 09:14:19

Tal vez me estoy perdiendo el punto.

La forma más confiable que he encontrado para finalizar la autenticación HTTP es cerrar el navegador y todas las ventanas del navegador. Puede cerrar una ventana del navegador usando Javascript, pero no creo que pueda cerrar todas las ventanas del navegador.

 1
Author: Toby Allen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-23 23:24:36

Mientras que los otros tienen razón al decir que es imposible cerrar la sesión de la autenticación http básica, hay formas de implementar la autenticación que se comportan de manera similar. Un appeoach obvio es usar auth_memcookie . Si realmente desea implementar la autenticación HTTP básica (es decir, usar los diálogos del navegador para iniciar sesión en un formulario HTTP) usando esto, simplemente establezca la autenticación en un separado .directorio protegido htaccess que contiene un script PHP que redirige de vuelta a donde llegó el usuario después de crear la sesión memcache.

 0
Author: symcbean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-01 13:03:57

Hay muchas respuestas complejas aquí. En mi caso particular encontré una solución limpia y simple para el cierre de sesión. Todavía tengo que probar en Edge. En mi página en la que he iniciado sesión, he colocado un enlace de cierre de sesión similar a este:

<a href="https://MyDomainHere.net/logout.html">logout</a>

Y en la cabeza de ese cierre de sesión.página html (que también está protegida por el .htaccess) Tengo una actualización de página similar a esta:

<meta http-equiv="Refresh" content="0; url=https://logout:[email protected]/" />

Donde dejaría las palabras "logout" en su lugar para borrar el nombre de usuario y la contraseña almacenados en caché para el sitio.

Admitiré que si se necesitaran varias páginas para poder iniciar sesión directamente desde el principio, cada uno de esos puntos de entrada necesitaría su propio cierre de sesión correspondiente.página html. De lo contrario, podría centralizar el cierre de sesión introduciendo un paso de gatekeeper adicional en el proceso antes de la solicitud de inicio de sesión real, requiriendo la entrada de una frase para llegar a un destino de inicio de sesión.

 0
Author: johnwayne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-18 08:26:36

La única manera efectiva que he encontrado para borrar las credenciales PHP_AUTH_DIGEST o PHP_AUTH_USER Y PHP_AUTH_PW es llamar al encabezado HTTP/1.1 401 Unauthorized.

function clear_admin_access(){
    header('HTTP/1.1 401 Unauthorized');
    die('Admin access turned off');
}
 -1
Author: CIRCLE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-07 15:59:04