Question

Quel est le moyen correct de vous déconnecter du dossier protégé par l'authentification HTTP?

Certaines solutions de contournement permettent d’atteindre cet objectif, mais elles sont potentiellement dangereuses car elles peuvent être buggées ou ne pas fonctionner dans certaines situations / navigateurs. C'est pourquoi je cherche une solution correcte et propre.

Était-ce utile?

La solution

Mu. Il n'y a pas de chemin correct , pas même cohérent sur tous les navigateurs.

Il s'agit d'un problème qui provient de la spécification HTTP (section 15.6):

  

Les clients HTTP existants et les agents d'utilisateurs conservent généralement l'authentification.     information indéfiniment. HTTP / 1.1. ne fournit pas une méthode pour un     serveur pour demander aux clients de supprimer ces informations d'identification mises en cache.

D'autre part, la section 10.4.2 dit:

  

Si la demande contient déjà des informations d’authentification, alors le 401    réponse indique que l'autorisation a été refusée pour les    lettres de créance. Si la réponse 401 contient le même défi que le    réponse préalable, et l'agent utilisateur a déjà tenté    authentification au moins une fois, l’utilisateur DEVRAIT se voir présenter le    entité qui a été donnée dans la réponse, puisque cette entité pourrait    inclure des informations de diagnostic pertinentes.

En d'autres termes, vous pourrez peut-être afficher à nouveau la zone de connexion (comme @ Karsten dit), mais le navigateur n'est pas obligé d'accepter votre requête - ne vous fiez donc pas trop à cette (mauvaise) fonctionnalité.

Autres conseils

Méthode qui fonctionne bien dans Safari. Fonctionne également dans Firefox et Opera, mais avec un avertissement.

Location: http://logout@yourserver.example.com/

Ceci indique au navigateur d'ouvrir l'URL avec un nouveau nom d'utilisateur, en remplaçant le précédent.

La réponse simple est que vous ne pouvez pas vous déconnecter de manière fiable de l'authentification http.

La réponse longue:
Http-auth (comme le reste de la spécification HTTP) est censé être sans état. Donc, " connecté " ou " déconnecté " n'est pas vraiment un concept qui a du sens. La meilleure façon de le voir est de demander, pour chaque requête HTTP (et rappelez-vous, le chargement d'une page est généralement constitué de plusieurs requêtes), "êtes-vous autorisé à faire ce que vous demandez?". Le serveur voit chaque demande comme nouvelle et n’ayant aucun lien avec les demandes précédentes.

Les navigateurs ont choisi de se rappeler les informations d'identification que vous leur avez données lors du premier 401 et de les renvoyer sans l'autorisation explicite de l'utilisateur pour les demandes suivantes. Il s’agit d’une tentative visant à donner à l’utilisateur le " connecté / déconnecté " modèle ils attendent, mais c'est purement un kludge. C'est le navigateur qui simule cette persistance d'état. Le serveur Web n'en a absolument pas conscience.

Donc, "déconnexion", dans le contexte de http-auth, est purement une simulation fournie par le navigateur et ne relève donc pas de l'autorité du serveur.

Oui, il y a des kludges. Mais ils brisent le repos (si cela vous est précieux) et ils ne sont pas fiables.

Si vous avez absolument besoin d'un modèle connecté / déconnecté pour l'authentification de votre site, le meilleur choix est un cookie de suivi, avec la persistance de l'état stocké sur le serveur (mysql, sqlite, flatfile, etc.). . Cela nécessitera que toutes les demandes soient évaluées, par exemple avec PHP.

Solution de contournement

Vous pouvez le faire en utilisant 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>

Ce qui est fait ci-dessus est:

  • pour IE - effacez simplement le cache d'authentification et redirigez quelque part

  • pour les autres navigateurs : envoyez un XMLHttpRequest en coulisse avec le nom de connexion et le mot de passe "déconnexion". Nous devons l’envoyer à un chemin qui retournera 200 OK à cette demande (c’est-à-dire qu’il ne devrait pas nécessiter d’authentification HTTP).

Remplacez '/ where / to / redirect' par un chemin vers lequel rediriger après la déconnexion et remplacez '/ path / that / will / return / 200 / OK' avec un chemin sur votre site qui retournera 200 OK.

Solution de contournement (ce n'est pas une solution propre, agréable (ou même efficace! Voir les commentaires)):

Désactivez ses informations d'identification une fois.

Vous pouvez déplacer votre logique d'authentification HTTP vers PHP en envoyant les en-têtes appropriés (s'ils ne sont pas connectés):

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

Et en analysant l'entrée avec:

Solution de contournement (ce n'est pas une solution propre, agréable (ou même efficace! Voir les commentaires)):

Désactivez ses informations d'identification une fois.

Vous pouvez déplacer votre logique d'authentification HTTP vers PHP en envoyant les en-têtes appropriés (s'ils ne sont pas connectés):

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

Et en analysant l'entrée avec:

<*>

Désactiver ses identifiants une seule fois devrait donc être une mince affaire.

SERVER['PHP_AUTH_USER'] // httpauth-user

Solution de contournement (ce n'est pas une solution propre, agréable (ou même efficace! Voir les commentaires)):

Désactivez ses informations d'identification une fois.

Vous pouvez déplacer votre logique d'authentification HTTP vers PHP en envoyant les en-têtes appropriés (s'ils ne sont pas connectés):

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

Et en analysant l'entrée avec:

<*>

Désactiver ses identifiants une seule fois devrait donc être une mince affaire.

SERVER['PHP_AUTH_PW'] // httpauth-password

Désactiver ses identifiants une seule fois devrait donc être une mince affaire.

Déconnexion de HTTP Basic Auth en deux étapes

Disons que j'ai un domaine d'authentification de base HTTP nommé "# 8220; Mot de passe protégé", et que Bob est connecté. Pour vous déconnecter, je crée 2 requêtes AJAX:

  1. Accédez au script / logout_step1. Il ajoute un utilisateur temporaire aléatoire à .htusers et répond avec son identifiant et son mot de passe.
  2. Accéder au script / logout_step2 authentifié avec le serveur temporaire nom d’utilisateur et mot de passe . Le script supprime l'utilisateur temporaire et ajoute cet en-tête à la réponse: Authentification WWW: royaume de base = "mot de passe protégé"

À ce stade, le navigateur a oublié les informations d'identification de Bob.

Ma solution au problème est la suivante. Vous pouvez trouver la fonction http_digest_parse , $ realm et $ users dans le deuxième exemple de cette page: http://php.net/manual/en/features.http-auth.php .

session_start();

function LogOut() {
  session_destroy();
  session_unset(

Ma solution au problème est la suivante. Vous pouvez trouver la fonction http_digest_parse , $ realm et $ users dans le deuxième exemple de cette page: http://php.net/manual/en/features.http-auth.php .

<*>SESSION['session_id']); session_unset(

Ma solution au problème est la suivante. Vous pouvez trouver la fonction http_digest_parse , $ realm et $ users dans le deuxième exemple de cette page: http://php.net/manual/en/features.http-auth.php .

<*>SESSION['logged']); header("Location: /", TRUE, 301); } function Login(){ global $realm; if (empty(

Ma solution au problème est la suivante. Vous pouvez trouver la fonction http_digest_parse , $ realm et $ users dans le deuxième exemple de cette page: http://php.net/manual/en/features.http-auth.php .

<*>SESSION['session_id'])) { session_regenerate_id();

Ma solution au problème est la suivante. Vous pouvez trouver la fonction http_digest_parse , $ realm et $ users dans le deuxième exemple de cette page: http://php.net/manual/en/features.http-auth.php .

<*>SESSION['session_id'] = session_id(); } if (!IsAuthenticated()) { header('HTTP/1.1 401 Unauthorized'); header('WWW-Authenticate: Digest realm="'.$realm. '",qop="auth",nonce="'.

Ma solution au problème est la suivante. Vous pouvez trouver la fonction http_digest_parse , $ realm et $ users dans le deuxième exemple de cette page: http://php.net/manual/en/features.http-auth.php .

<*>SESSION['session_id'].'",opaque="'.md5($realm).'"');

Ma solution au problème est la suivante. Vous pouvez trouver la fonction http_digest_parse , $ realm et $ users dans le deuxième exemple de cette page: http://php.net/manual/en/features.http-auth.php .

<*>SESSION['logged'] = False; die('Access denied.'); }

Ma solution au problème est la suivante. Vous pouvez trouver la fonction http_digest_parse , $ realm et $ users dans le deuxième exemple de cette page: http://php.net/manual/en/features.http-auth.php .

<*>SESSION['logged'] = True; } function IsAuthenticated(){ global $realm; global $users; if (empty(

Ma solution au problème est la suivante. Vous pouvez trouver la fonction http_digest_parse , $ realm et $ users dans le deuxième exemple de cette page: http://php.net/manual/en/features.http-auth.php .

<*>SERVER['PHP_AUTH_DIGEST'])) return False; // check PHP_AUTH_DIGEST if (!($data = http_digest_parse(

Ma solution au problème est la suivante. Vous pouvez trouver la fonction http_digest_parse , $ realm et $ users dans le deuxième exemple de cette page: http://php.net/manual/en/features.http-auth.php .

<*>SERVER['PHP_AUTH_DIGEST'])) || !isset($users[$data['username']])) return False;// invalid username $A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]); $A2 = md5(

Ma solution au problème est la suivante. Vous pouvez trouver la fonction http_digest_parse , $ realm et $ users dans le deuxième exemple de cette page: http://php.net/manual/en/features.http-auth.php .

<*>SERVER['REQUEST_METHOD'].':'.$data['uri']); // Give session id instead of data['nonce'] $valid_response = md5($A1.':'.

Ma solution au problème est la suivante. Vous pouvez trouver la fonction http_digest_parse , $ realm et $ users dans le deuxième exemple de cette page: http://php.net/manual/en/features.http-auth.php .

<*>SESSION['session_id'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2); if ($data['response'] != $valid_response) return False; return True; }

Généralement, une fois qu'un navigateur a demandé des informations d'identification à l'utilisateur et les a fournies à un site Web particulier, il continue à le faire sans autre invite. Contrairement aux différentes manières dont vous pouvez supprimer les cookies côté client, je ne connais pas de méthode similaire pour demander au navigateur d’oublier les informations d’authentification fournies.

Trac - par défaut - utilise également l'authentification HTTP. La déconnexion ne fonctionne pas et ne peut pas être corrigée:

  
      
  • Ceci est un problème avec le schéma d'authentification HTTP lui-même et nous ne pouvons rien faire dans Trac pour le réparer correctement.
  •   
  • Il n'existe actuellement aucune solution de contournement (JavaScript ou autre) compatible avec tous les principaux navigateurs.
  •   

De: http://trac.edgewall.org / ticket / 791 # commentaire: 103

On dirait qu’il n’ya pas de réponse satisfaisante à la question. Cette question a été rapportée il y a sept ans et cela a un sens parfait: HTTP est sans état. Une demande est effectuée avec les informations d'authentification ou non. Mais c'est le client qui envoie la demande, pas le serveur qui la reçoit. Le serveur peut uniquement indiquer si une URI de requête nécessite une autorisation ou non.

J'avais besoin de réinitialiser l'autorisation .htaccess alors j'ai utilisé ceci:

<?php
if (!isset(

J'avais besoin de réinitialiser l'autorisation .htaccess alors j'ai utilisé ceci:

<*>

trouvé ici: http://php.net/manual/en/features.http-auth.php

Allez comprendre.

Un certain nombre de solutions résident sur cette page et il est même noté en bas: Lynx, ne supprime pas l’authentification comme les autres navigateurs;)

Je l'ai testé sur mes navigateurs installés et, une fois fermé, chaque navigateur semble requérir systématiquement une nouvelle autorisation lors de la rentrée.

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; } ?>

trouvé ici: http://php.net/manual/en/features.http-auth.php

Allez comprendre.

Un certain nombre de solutions résident sur cette page et il est même noté en bas: Lynx, ne supprime pas l’authentification comme les autres navigateurs;)

Je l'ai testé sur mes navigateurs installés et, une fois fermé, chaque navigateur semble requérir systématiquement une nouvelle autorisation lors de la rentrée.

Ce n'est peut-être pas la solution recherchée, mais je l'ai résolue comme ceci. J'ai 2 scripts pour le processus de déconnexion.

logout.php

<?php
header("Location: http://.@domain.com/log.php");
?>

log.php

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

De cette façon, je ne reçois pas d'avertissement et ma session est terminée

Si je comprends bien, il n’existe aucun moyen propre d’implémenter un " déconnexion " fonctionne lors de l’utilisation de l’authentification htaccess (c'est-à-dire basée sur HTTP).

En effet, cette authentification utilise le code d'erreur HTTP "401" pour indiquer au navigateur que des informations d'identification sont requises. Le navigateur invite alors l'utilisateur à fournir les informations d'identification. À partir de ce moment et jusqu'à la fermeture du navigateur, les informations d'identification seront toujours envoyées sans autre invite.

La meilleure solution que j'ai trouvée jusqu'à présent est (c'est en quelque sorte un pseudo-code, le $ isLoggedIn est une pseudo-variable pour http auth):

Au moment de la "déconnexion" stockez simplement des informations dans la session en indiquant que cet utilisateur est réellement déconnecté.

function logout()
{
  //$isLoggedIn = false; //This does not work (point of this question)
  

La meilleure solution que j'ai trouvée jusqu'à présent est (c'est en quelque sorte un pseudo-code, le $ isLoggedIn est une pseudo-variable pour http auth):

Au moment de la "déconnexion" stockez simplement des informations dans la session en indiquant que cet utilisateur est réellement déconnecté.

function isLoggedIn()
{
  return $isLoggedIn && !

La meilleure solution que j'ai trouvée jusqu'à présent est (c'est en quelque sorte un pseudo-code, le $ isLoggedIn est une pseudo-variable pour http auth):

Au moment de la "déconnexion" stockez simplement des informations dans la session en indiquant que cet utilisateur est réellement déconnecté.

function logout()
{
  //$isLoggedIn = false; //This does not work (point of this question)
  

La meilleure solution que j'ai trouvée jusqu'à présent est (c'est en quelque sorte un pseudo-code, le $ isLoggedIn est une pseudo-variable pour http auth):

Au moment de la "déconnexion" stockez simplement des informations dans la session en indiquant que cet utilisateur est réellement déconnecté.

<*>

À l'endroit où je vérifie l'authentification, je développe la condition suivante:

<*>

La session étant liée à l'état de l'authentification http, l'utilisateur reste déconnecté tant qu'il laisse le navigateur ouvert et tant que l'authentification http persiste dans le navigateur.

SESSION['logout'] = true; }

À l'endroit où je vérifie l'authentification, je développe la condition suivante:

<*>

La session étant liée à l'état de l'authentification http, l'utilisateur reste déconnecté tant qu'il laisse le navigateur ouvert et tant que l'authentification http persiste dans le navigateur.

SESSION['logout']; }

À l'endroit où je vérifie l'authentification, je développe la condition suivante:

<*>

La session étant liée à l'état de l'authentification http, l'utilisateur reste déconnecté tant qu'il laisse le navigateur ouvert et tant que l'authentification http persiste dans le navigateur.

SESSION['logout'] = true; }

À l'endroit où je vérifie l'authentification, je développe la condition suivante:

<*>

La session étant liée à l'état de l'authentification http, l'utilisateur reste déconnecté tant qu'il laisse le navigateur ouvert et tant que l'authentification http persiste dans le navigateur.

Peut-être que je manque le point.

Le moyen le plus fiable que j'ai trouvé de mettre fin à l'authentification HTTP consiste à fermer le navigateur et toutes les fenêtres du navigateur. Vous pouvez fermer une fenêtre de navigateur à l'aide de Javascript, mais je ne pense pas que vous puissiez fermer toutes les fenêtres de navigateur.

Le seul moyen efficace d'effacer les informations d'identification PHP_AUTH_DIGEST ou PHP_AUTH_USER AND PHP_AUTH_PW est d'appeler l'en-tête . HTTP / 1.1 401 Non autorisé .

function clear_admin_access(){
    header('HTTP/1.1 401 Unauthorized');
    die('Admin access turned off');
}

Alors que les autres ont raison de dire qu'il est impossible de se déconnecter de l'authentification http de base, il existe des moyens de mettre en œuvre l'authentification qui se comporte de la même manière. Une solution évidente consiste à utiliser auth_memcookie . Si vous voulez vraiment implémenter l'authentification HTTP de base (c'est-à-dire utiliser les boîtes de dialogue du navigateur pour vous connecter au lieu d'un formulaire HTTP), utilisez simplement ceci: définissez l'authentification sur un répertoire protégé .htaccess séparé contenant un script PHP qui redirige vers l'endroit où l'utilisateur est arrivé après créer la session memcache.

Il y a beaucoup de réponses géniales - complexes - ici. Dans mon cas particulier, j'ai trouvé un correctif clair et simple pour la déconnexion. Je n'ai pas encore testé dans Edge. Sur ma page à laquelle je me suis connecté, j'ai placé un lien de déconnexion similaire à celui-ci:

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

Et dans l'en-tête de cette page logout.html (qui est également protégée par le .htaccess), j'ai un rafraîchissement de page semblable à celui-ci:

<meta http-equiv="Refresh" content="0; url=https://logout:logout@MyDomainHere.net/" />

Où vous laisseriez les mots " déconnexion " en place pour effacer le nom d'utilisateur et le mot de passe mis en cache pour le site.

Je conviens que si plusieurs pages devaient pouvoir être directement connectées depuis le début, chacun de ces points d’entrée aurait besoin de sa propre page logout.html correspondante. Sinon, vous pouvez centraliser la déconnexion en introduisant une étape supplémentaire de contrôle d'accès dans le processus avant l'invite de connexion proprement dite, ce qui nécessite la saisie d'une phrase pour atteindre une destination de connexion.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top