Comment déconnecter un utilisateur du site Web en utilisant l'authentification de base?

est-il possible de déconnecter un utilisateur d'un site web s'il utilise une authentification de base?

tuer session n'est pas suffisant, puisque, une fois l'utilisateur est authentifié, chaque demande contient des informations de connexion, de sorte que l'utilisateur est automatiquement connecté la prochaine fois qu'il/elle accède au site en utilisant les mêmes justificatifs d'identité.

la seule solution jusqu'à présent est de fermer le navigateur, mais ce n'est pas acceptable du point de vue de la convivialité.

230
demandé sur KyleMit 2008-10-24 17:21:35

18 réponses

L'authentification de base n'a pas été conçue pour gérer la déconnexion. Vous pouvez le faire, mais pas complètement automatiquement.

ce que vous avez à faire est de demander à l'utilisateur de cliquer sur un lien de déconnexion, et d'envoyer un ‘401 non autorisé’ en réponse, en utilisant le même domaine et au même niveau de dossier URL que la normale 401 que vous envoyez demandant une connexion.

ils doivent être dirigés vers l'entrée de mauvais justificatifs d'identité suivant, par exemple. un nom d'utilisateur et un mot de passe vierges, et en réponse vous renvoyez "Vous êtes connecté avec succès" de la page. Les justificatifs d'identité erronés/Vierges écraseront alors les justificatifs d'identité corrects précédents.

en bref, le script de déconnexion inverse la logique du script de connexion, ne retournant la page de succès que si l'utilisateur n'est pas en passant les bonnes références.

la question Est de savoir si la boîte de mot de passe" n'entrez pas votre mot de passe", quelque peu curieuse, sera acceptée par l'utilisateur. Gestionnaires de mots de passe qui tentent de auto-remplir le mot de passe peut également obtenir de la manière ici.

Modifier pour ajouter en réponse au commentaire: re-log-in est un problème légèrement différent (sauf si vous avez besoin d'une déconnexion/connexion en deux étapes évidemment). Vous devez rejeter (401) la première tentative d'accéder au lien relogin, plutôt que d'accepter la seconde (qui a probablement un nom d'utilisateur/mot de passe différent). Il existe quelques façons dont vous pouvez faire cela. On serait d'inclure le nom d'utilisateur dans le lien de déconnexion (par exemple. /reconnectez-vous?nom d'utilisateur), et rejet lorsque les justificatifs correspondent au nom d'utilisateur.

145
répondu bobince 2008-10-24 15:06:15

Un complément à la réponse par bobince ...

avec Ajax vous pouvez avoir votre lien/bouton' Déconnexion ' relié à une fonction Javascript. Demandez à cette fonction d'envoyer le XMLHttpRequest avec un mauvais nom d'utilisateur et mot de passe. Ça devrait rapporter un 401. Puis définissez le document.emplacement retour à la page de pré-connexion. De cette façon, l'utilisateur ne verra jamais la boîte de dialogue de connexion supplémentaire pendant la déconnexion, ni n'aura à se rappeler de mettre de mauvaises références.

180
répondu system PAUSE 2009-01-29 18:56:08

demandez à l'utilisateur de cliquer sur un lien vers https://log:out@example.com / . Cela écrasera les justificatifs d'identité existants avec ceux qui ne sont pas valides; les déconnecter.

166
répondu Matthew Welborn 2014-09-16 11:13:54

vous pouvez le faire entièrement en JavaScript:

IE possède (depuis longtemps) une API standard pour effacer le cache D'authentification de base:

document.execCommand("ClearAuthenticationCache")

devrait revenir vrai quand ça marche. Renvoie false, undefined ou blows up sur d'autres navigateurs.

les nouveaux navigateurs (à partir de décembre 2012: Chrome, FireFox, Safari) ont un comportement" magique". S'ils voient une réussie demande d'autorisation de base avec tout faux autre nom d'utilisateur (disons logout ) ils effacent les informations d'identification du cache et peut-être le configurent pour ce nouveau nom d'utilisateur bidon, dont vous devez vous assurer qu'il ne s'agit pas d'un nom d'utilisateur valide pour visualiser le contenu.

exemple de base:

var p = window.location.protocol + '//'
// current location must return 200 OK for this GET
window.location = window.location.href.replace(p, p + 'logout:password@')

une façon" asynchrone "de faire ce qui précède est de faire un appel AJAX en utilisant le nom d'utilisateur logout . Exemple:

(function(safeLocation){
    var outcome, u, m = "You should be logged out now.";
    // IE has a simple solution for it - API:
    try { outcome = document.execCommand("ClearAuthenticationCache") }catch(e){}
    // Other browsers need a larger solution - AJAX call with special user name - 'logout'.
    if (!outcome) {
        // Let's create an xmlhttp object
        outcome = (function(x){
            if (x) {
                // the reason we use "random" value for password is 
                // that browsers cache requests. changing
                // password effectively behaves like cache-busing.
                x.open("HEAD", safeLocation || location.href, true, "logout", (new Date()).getTime().toString())
                x.send("")
                // x.abort()
                return 1 // this is **speculative** "We are done." 
            } else {
                return
            }
        })(window.XMLHttpRequest ? new window.XMLHttpRequest() : ( window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : u ))
    }
    if (!outcome) {
        m = "Your browser is too old or too weird to support log out functionality. Close all windows and restart the browser."
    }
    alert(m)
    // return !!outcome
})(/*if present URI does not return 200 OK for GET, set some other 200 OK location here*/)

Vous pouvez en faire un bookmarklet trop:

javascript:(function(c){var a,b="You should be logged out now.";try{a=document.execCommand("ClearAuthenticationCache")}catch(d){}a||((a=window.XMLHttpRequest?new window.XMLHttpRequest:window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):void 0)?(a.open("HEAD",c||location.href,!0,"logout",(new Date).getTime().toString()),a.send(""),a=1):a=void 0);a||(b="Your browser is too old or too weird to support log out functionality. Close all windows and restart the browser.");alert(b)})(/*pass safeLocation here if you need*/);

57
répondu ddotsenko 2013-03-01 01:01:20

la fonction suivante est confirmée pour Firefox 40, Chrome 44, Opera 31 et IE 11.

Bowser est utilisé pour la détection du navigateur, jQuery est également utilisé.



- secUrl est l'url d'une zone protégée par mot de passe à partir de laquelle vous pouvez vous déconnecter.

- redirUrl est l'url d'une zone non protégée par mot de passe (page de succès de déconnexion).

- vous pourriez augmenter le minuteur de redirection (actuellement 200ms).

function logout(secUrl, redirUrl) {
    if (bowser.msie) {
        document.execCommand('ClearAuthenticationCache', 'false');
    } else if (bowser.gecko) {
        $.ajax({
            async: false,
            url: secUrl,
            type: 'GET',
            username: 'logout'
        });
    } else if (bowser.webkit) {
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.open("GET", secUrl, true);
        xmlhttp.setRequestHeader("Authorization", "Basic logout");
        xmlhttp.send();
    } else {
        alert("Logging out automatically is unsupported for " + bowser.name
            + "\nYou must close the browser to log out.");
    }
    setTimeout(function () {
        window.location.href = redirUrl;
    }, 200);
}
12
répondu mthoring 2015-09-01 07:24:57

ce n'est pas directement possible avec Basic-Authentication.

il n'y a aucun mécanisme dans la spécification HTTP pour que le serveur dise au navigateur d'arrêter d'envoyer les informations d'identification que l'Utilisateur a déjà présentées.

il y a des" hacks " (voir autres réponses) impliquant typiquement l'utilisation de XMLHttpRequest pour envoyer une requête HTTP avec des informations d'identification incorrectes pour écraser ceux fournis à l'origine.

10
répondu Alnitak 2015-10-09 10:25:23

voici un exemple Javascript très simple utilisant jQuery:

function logout(to_url) {
    var out = window.location.href.replace(/:\/\//, '://log:out@');

    jQuery.get(out).error(function() {
        window.location = to_url;
    });
}

cet utilisateur de connexion sans lui montrer le navigateur se connecter à nouveau, puis le rediriger vers un déconnecté page

9
répondu Romuald Brunet 2014-06-10 12:35:08

c'est en fait assez simple.

il suffit de visiter ce qui suit dans votre navigateur et d'utiliser des justificatifs d'identité erronés: http://username:password@yourdomain.com

Qui devrait "session".

6
répondu Chiedo 2015-02-18 18:59:17

cela fonctionne pour IE / Netscape / Chrome:

      function ClearAuthentication(LogOffPage) 
  {
     var IsInternetExplorer = false;    

     try
     {
         var agt=navigator.userAgent.toLowerCase();
         if (agt.indexOf("msie") != -1) { IsInternetExplorer = true; }
     }
     catch(e)
     {
         IsInternetExplorer = false;    
     };

     if (IsInternetExplorer) 
     {
        // Logoff Internet Explorer
        document.execCommand("ClearAuthenticationCache");
        window.location = LogOffPage;
     }
     else 
     {
        // Logoff every other browsers
    $.ajax({
         username: 'unknown',
         password: 'WrongPassword',
             url: './cgi-bin/PrimoCgi',
         type: 'GET',
         beforeSend: function(xhr)
                 {
            xhr.setRequestHeader("Authorization", "Basic AAAAAAAAAAAAAAAAAAA=");
         },

                 error: function(err)
                 {
                    window.location = LogOffPage;
             }
    });
     }
  }


  $(document).ready(function () 
  {
      $('#Btn1').click(function () 
      {
         // Call Clear Authentication 
         ClearAuthentication("force_logout.html"); 
      });
  });          
5
répondu Claudio 2013-05-20 08:52:50
function logout() {
  var userAgent = navigator.userAgent.toLowerCase();

  if (userAgent.indexOf("msie") != -1) {
    document.execCommand("ClearAuthenticationCache", false);
  }

  xhr_objectCarte = null;

  if(window.XMLHttpRequest)
    xhr_object = new XMLHttpRequest();
  else if(window.ActiveXObject)
    xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
  else
    alert ("Your browser doesn't support XMLHTTPREQUEST");

  xhr_object.open ('GET', 'http://yourserver.com/rep/index.php', false, 'username', 'password');
  xhr_object.send ("");
  xhr_object = null;

  document.location = 'http://yourserver.com'; 
  return false;
}
2
répondu Charlie 2015-02-06 15:37:43
 function logout(url){
    var str = url.replace("http://", "http://" + new Date().getTime() + "@");
    var xmlhttp;
    if (window.XMLHttpRequest) xmlhttp=new XMLHttpRequest();
    else xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState==4) location.reload();
    }
    xmlhttp.open("GET",str,true);
    xmlhttp.setRequestHeader("Authorization","Basic xxxxxxxxxx")
    xmlhttp.send();
    return false;
}
2
répondu Sushovan Mukherjee 2015-03-13 16:50:32

tout ce que vous avez besoin est rediriger l'utilisateur sur un certain logout URL et retourner 401 Unauthorized erreur sur elle. Sur la page d'erreur (qui doit être accessible sans autorisation de base), vous devez fournir un lien complet vers votre page d'accueil (y compris scheme et hostname). L'utilisateur clique sur ce lien et le navigateur demande à nouveau des justificatifs d'identité.

exemple pour Nginx:

location /logout {
    return 401;
}

error_page 401 /errors/401.html;

location /errors {
    auth_basic off;
    ssi        on;
    ssi_types  text/html;
    alias /home/user/errors;
}

page D'erreur /home/user/errors/401.html :

<!DOCTYPE html>
<p>You're not authorised. <a href="<!--# echo var="scheme" -->://<!--# echo var="host" -->/">Login</a>.</p>
1
répondu Envek 2015-12-12 14:12:34

basé sur ce que j'ai lu ci-dessus, j'ai eu une solution simple qui fonctionne sur n'importe quel navigateur:

1) sur votre page de déconnexion vous appelez un ajax à votre fin arrière de connexion. Votre identifiant doit accepter de déconnexion de l'utilisateur. Une fois que l'extrémité arrière accepte, le navigateur effacer l'utilisateur actuel et suppose l'utilisateur "déconnexion".

$.ajax({
    async: false,
    url: 'http://your_login_backend',
    type: 'GET',
    username: 'logout'
});      

setTimeout(function () {
    window.location.href = 'http://normal_index';
}, 200);

2) Maintenant, lorsque l'utilisateur est revenu au fichier index normal, il va essayer d'entrer automatiquement dans le système avec l'utilisateur "logout", sur ce la deuxième fois, vous devez le bloquer par réponse avec 401 pour invoquer la boîte de dialogue login/Mot de passe.

3) Il y a plusieurs façons de faire cela, j'ai créé deux back ends de connexion, un qui accepte l'utilisateur de déconnexion et un qui ne le fait pas. Ma page de connexion normale utilise celle qui n'accepte pas, ma page de déconnexion utilise celle qui l'accepte.

1
répondu Foad 2017-03-02 15:54:44
  • utiliser un identifiant de session (cookie)
  • invalider L'ID de session sur le serveur
  • N'acceptez pas les utilisateurs avec des ID de session invalides
0
répondu Tomalak 2008-10-24 13:24:46

ce JavaScript doit fonctionner pour tous les navigateurs de la dernière version:

//Detect Browser
var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
    // Opera 8.0+ (UA detection to detect Blink/v8-powered Opera)
var isFirefox = typeof InstallTrigger !== 'undefined';   // Firefox 1.0+
var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
    // At least Safari 3+: "[object HTMLElementConstructor]"
var isChrome = !!window.chrome && !isOpera;              // Chrome 1+
var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
var Host = window.location.host;


//Clear Basic Realm Authentication
if(isIE){
//IE
    document.execCommand("ClearAuthenticationCache");
    window.location = '/';
}
else if(isSafari)
{//Safari. but this works mostly on all browser except chrome
    (function(safeLocation){
        var outcome, u, m = "You should be logged out now.";
        // IE has a simple solution for it - API:
        try { outcome = document.execCommand("ClearAuthenticationCache") }catch(e){}
        // Other browsers need a larger solution - AJAX call with special user name - 'logout'.
        if (!outcome) {
            // Let's create an xmlhttp object
            outcome = (function(x){
                if (x) {
                    // the reason we use "random" value for password is 
                    // that browsers cache requests. changing
                    // password effectively behaves like cache-busing.
                    x.open("HEAD", safeLocation || location.href, true, "logout", (new Date()).getTime().toString())
                    x.send("");
                    // x.abort()
                    return 1 // this is **speculative** "We are done." 
                } else {
                    return
                }
            })(window.XMLHttpRequest ? new window.XMLHttpRequest() : ( window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : u )) 
        }
        if (!outcome) {
            m = "Your browser is too old or too weird to support log out functionality. Close all windows and restart the browser."
        }
        alert(m);
        window.location = '/';
        // return !!outcome
    })(/*if present URI does not return 200 OK for GET, set some other 200 OK location here*/)
}
else{
//Firefox,Chrome
    window.location = 'http://log:out@'+Host+'/';
}
0
répondu Amit Shah 2015-07-21 05:16:23

ajoutez ceci à votre demande:

@app.route('/logout')
def logout():
    return ('Logout', 401, {'WWW-Authenticate': 'Basic realm="Login required"'})
0
répondu Amir Mofakhar 2015-09-18 13:29:40

j'ai mis à jour la solution de mthoring pour les versions modernes de Chrome:

function logout(secUrl, redirUrl) {
    if (bowser.msie) {
        document.execCommand('ClearAuthenticationCache', 'false');
    } else if (bowser.gecko) {
        $.ajax({
            async: false,
            url: secUrl,
            type: 'GET',
            username: 'logout'
        });
    } else if (bowser.webkit || bowser.chrome) {
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.open(\"GET\", secUrl, true);
        xmlhttp.setRequestHeader(\"Authorization\", \"Basic logout\");\
        xmlhttp.send();
    } else {
// http://stackoverflow.com/questions/5957822/how-to-clear-basic-authentication-details-in-chrome
        redirUrl = url.replace('http://', 'http://' + new Date().getTime() + '@');
    }
    setTimeout(function () {
        window.location.href = redirUrl;
    }, 200);
}
0
répondu Max 2017-05-15 23:15:31


    function logout(secUrl, redirUrl) {
        if (bowser.msie) {
            document.execCommand('ClearAuthenticationCache', 'false');
        } else if (bowser.gecko) {
            $.ajax({
                async: false,
                url: secUrl,
                type: 'GET',
                username: 'logout'
            });
        } else if (bowser.webkit) {
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.open("GET", secUrl, true);
            xmlhttp.setRequestHeader("Authorization", "Basic logout");
            xmlhttp.send();
        } else {
            alert("Logging out automatically is unsupported for " + bowser.name
                + "\nYou must close the browser to log out.");
        }
        setTimeout(function () {
            window.location.href = redirUrl;
        }, 200);
    }

j'ai essayé d'utiliser ce qui précède de la manière suivante.

?php
    ob_start();
    session_start();
    require_once 'dbconnect.php';

    // if session is not set this will redirect to login page
    if( !isset($_SESSION['user']) ) {
        header("Location: index.php");
        exit;
    }
    // select loggedin users detail
    $res=mysql_query("SELECT * FROM users WHERE userId=".$_SESSION['user']);
    $userRow=mysql_fetch_array($res);
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Welcome - <?php echo $userRow['userEmail']; ?></title>
<link rel="stylesheet" href="assets/css/bootstrap.min.css" type="text/css"  />
<link rel="stylesheet" href="style.css" type="text/css" />

    <script src="assets/js/bowser.min.js"></script>
<script>
//function logout(secUrl, redirUrl)
//bowser = require('bowser');
function logout(secUrl, redirUrl) {
alert(redirUrl);
    if (bowser.msie) {
        document.execCommand('ClearAuthenticationCache', 'false');
    } else if (bowser.gecko) {
        $.ajax({
            async: false,
            url: secUrl,
            type: 'GET',
            username: 'logout'
        });
    } else if (bowser.webkit) {
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.open("GET", secUrl, true);
        xmlhttp.setRequestHeader("Authorization", "Basic logout");
        xmlhttp.send();
    } else {
        alert("Logging out automatically is unsupported for " + bowser.name
            + "\nYou must close the browser to log out.");
    }
    window.location.assign(redirUrl);
    /*setTimeout(function () {
        window.location.href = redirUrl;
    }, 200);*/
}


function f1()
    {
       alert("f1 called");
       //form validation that recalls the page showing with supplied inputs.    
    }
</script>
</head>
<body>

    <nav class="navbar navbar-default navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="http://www.codingcage.com">Coding Cage</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
          <ul class="nav navbar-nav">
            <li class="active"><a href="http://www.codingcage.com/2015/01/user-registration-and-login-script-using-php-mysql.html">Back to Article</a></li>
            <li><a href="http://www.codingcage.com/search/label/jQuery">jQuery</a></li>
            <li><a href="http://www.codingcage.com/search/label/PHP">PHP</a></li>
          </ul>
          <ul class="nav navbar-nav navbar-right">

            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
              <span class="glyphicon glyphicon-user"></span>&nbsp;Hi' <?php echo $userRow['userEmail']; ?>&nbsp;<span class="caret"></span></a>
              <ul class="dropdown-menu">
                <li><a href="logout.php?logout"><span class="glyphicon glyphicon-log-out"></span>&nbsp;Sign Out</a></li>
              </ul>
            </li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav> 

    <div id="wrapper">

    <div class="container">

        <div class="page-header">
        <h3>Coding Cage - Programming Blog</h3>
        </div>

        <div class="row">
        <div class="col-lg-12" id="div_logout">
        <h1 onclick="logout(window.location.href, 'www.espncricinfo.com')">MichaelA1S1! Click here to see log out functionality upon click inside div</h1>
        </div>
        </div>

    </div>

    </div>

    <script src="assets/jquery-1.11.3-jquery.min.js"></script>
    <script src="assets/js/bootstrap.min.js"></script>


</body>
</html>
<?php ob_end_flush(); ?>

mais il ne vous redirige à un nouvel endroit. Pas de déconnexion.

0
répondu Hasan Junaid Hashmi 2018-09-20 08:38:09