Comment déconnecter l'utilisateur du site Web en utilisant l'authentification BASIC?


279

Est-il possible de déconnecter un utilisateur d'un site Web s'il utilise l'authentification de base?

Tuer une session ne suffit pas, car une fois que l'utilisateur est authentifié, chaque demande contient des informations de connexion, de sorte que l'utilisateur est automatiquement connecté la prochaine fois qu'il accède au site en utilisant les mêmes informations d'identification.

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


1
Juste curieux. Pourquoi veux-tu faire cela?
DOK

17
Pour pouvoir vous connecter en tant qu'utilisateur différent.
Marko

16
@DOK - C'est un truc de piratage social standard: les utilisateurs devraient pouvoir se déconnecter tout en laissant leur navigateur ouvert. Supposons qu'un de vos utilisateurs accède au site sur une machine publique? Ils doivent se déconnecter explicitement afin que le prochain utilisateur ne puisse pas accéder au site en tant que lui.
Keith

@DOK Il y a aussi le problème qui empêche l'utilisateur de se déconnecter du site. Le serveur peut effacer le cookie d'autorisation, et même le cookie de session. Mais lorsque le navigateur va charger la /page, ils se reconnecteront automatiquement.
Ian Boyd

J'utilise la méthode qui envoie une fausse demande de déconnexion, mais elle verrouille l'utilisateur dans le client car il y a une limitation stricte que 3 fois la connexion a échoué dans AD. Alors, suggérez d'utiliser cette méthode (envoyez une fausse demande) avec prudence.
Qianchao Pan

Réponses:


170

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 devez faire, c'est que l'utilisateur clique sur un lien de déconnexion et envoie un `` 401 non autorisé '' en réponse, en utilisant le même domaine et au même niveau de dossier URL que le 401 normal que vous envoyez en demandant une connexion.

Ils doivent être dirigés pour saisir ensuite des informations d'identification erronées, par exemple. un nom d'utilisateur et un mot de passe vierges, et en réponse, vous renvoyez une page «Vous avez réussi à vous déconnecter». Les informations d'identification incorrectes / vierges remplaceront alors les informations d'identification correctes précédentes.

En bref, le script de déconnexion inverse la logique du script de connexion, ne renvoyant la page de réussite que si l'utilisateur ne transmet pas les bonnes informations d'identification.

La question est de savoir si la boîte de mot de passe quelque peu curieuse «ne saisissez pas votre mot de passe» rencontrera l'acceptation des utilisateurs. Les gestionnaires de mots de passe qui essaient de remplir automatiquement le mot de passe peuvent également vous gêner ici.

Modifier pour ajouter en réponse au commentaire: la reconnexion 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ès au lien de reconnexion, puis accepter la seconde (qui a vraisemblablement un nom d'utilisateur / mot de passe différent). Il existe plusieurs façons de procéder. La première consisterait à inclure le nom d'utilisateur actuel dans le lien de déconnexion (par exemple. / Relogin? Nom d'utilisateur) et à le rejeter lorsque les informations d'identification correspondent au nom d'utilisateur.


2
Je vais essayer cette approche. Le point de déconnexion (dans ce cas) est de permettre à l'utilisateur de se connecter en tant qu'utilisateur différent, c'est donc une solution parfaitement acceptable. Quant au mot de passe à remplissage automatique, il appartient à l'utilisateur de l'utiliser ou non. Merci
Marko

Est-ce toujours le seul moyen? J'ai fait une implémentation ASP.Net MVC et jQuery qui fonctionne, mais je ne suis toujours pas satisfait: stackoverflow.com/questions/6277919
Keith

@Keith: Toujours seulement cela et la réponse de systemPAUSE (qui ne fonctionne pas sur tous les navigateurs, mais qui est plus fluide que l'approche manuelle lorsqu'elle fonctionne).
bobince

16
Le W3C est tellement actif sur la spécification HTML. Mais la spécification HTTP languit. Le W3C aurait dû résoudre ce problème il y a environ deux décennies. Avec l'augmentation de l'utilisation des services REST, une méthode d'authentification native robuste est de mise.
Dojo

9
Cela ne semble pas fonctionner correctement dans la navigation Chrome 46 sur localhost. Chrome semble conserver à la fois l'ancien (correct) mot de passe et le nouveau mot de passe que vous spécifiez. Après avoir accédé à la page de déconnexion, Chrome utilise correctement le nouveau mot de passe JUSQU'À CE QU'IL RENCONTRE UN 401 NON AUTORISÉ SUR UNE PAGE DE VOTRE SITE. Après le premier 401, Chrome revient à l'ancien (correct) mot de passe. Il n'a donc vraiment pas supprimé le mot de passe en premier lieu.
vancan1ty

196

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

Avec Ajax, vous pouvez avoir votre lien / bouton de déconnexion câblé à une fonction Javascript. Demandez à cette fonction d'envoyer le XMLHttpRequest avec un mauvais nom d'utilisateur et mot de passe. Cela devrait récupérer un 401. Ensuite, définissez document.location sur la page de pré-connexion. De cette façon, l'utilisateur ne verra jamais la boîte de dialogue de connexion supplémentaire lors de la déconnexion, ni n'aura à se rappeler de saisir de mauvaises informations d'identification.


12
Bon hack, avoir l'utilisateur saisir manuellement de mauvaises informations d'identification n'est probablement pas acceptable pour la plupart des applications Web.
BillMan

1
Assurez-vous simplement que XMLHttpRequest n'est pas défini pour être asynchrone ou vous pouvez constater que la redirection via aura lieu avant la fin de la demande de déconnexion.
davidjb

5
Vous pouvez également utiliser la même astuce pour la connexion. De cette façon, vous pouvez personnaliser la boîte de dialogue de connexion sans avoir à modifier la méthode d'authentification du serveur. Cet article donne quelques bonnes idées: http://www.peej.co.uk/articles/http-auth-with-html-forms.html
Stijn de Witt

1
@davidjb Étant donné que les demandes synchrones sont désormais considérées comme obsolètes, une solution alternative pourrait consister à rediriger l'utilisateur dans le rappel de la demande asynchrone.
Hayden Schiff

1
David: Chrome permet désormais cela pour les XHR, et je peux confirmer qu'il fonctionne toujours dans Chrome Canary. bugs.chromium.org/p/chromium/issues/detail?id=435547
CpnCrunch

192

Demandez à l'utilisateur de cliquer sur un lien vers https: // log: out@example.com/ . Cela remplacera les informations d'identification existantes par des informations non valides; les déconnecter.


19
Pourquoi celui-ci n'obtient-il pas plus de votes positifs? Cela me semble être une solution simple et efficace. Y a-t-il des problèmes connus avec cette approche?
amoebe du

35
Cela ne fonctionnerait plus dans Chrome, qui, pour des raisons de sécurité, ignore les informations d'identification dans une URL.
Thom

5
Cela a fonctionné pour moi :) J'utilise la version 32.0.1700.102 de Chrome
abottoni

6
problème: en utilisant la version 39.0 de chrome, lorsque je clique sur le lien de déconnexion via cette méthode, Chrome se souvient des informations d'identification de connexion incorrectes et demande de nouvelles informations d'identification de connexion à chaque chargement de page, jusqu'à ce que je me rende sur example.com sans aucune information d'identification de connexion spécifiée, pour effacer la mémoire de chrome.
Scott

4
Bonjour, je ne peux pas l'utiliser pour https sur Chrome.
thienkhoi tran

67

Vous pouvez le faire entièrement en JavaScript:

IE a (depuis longtemps) une API standard pour effacer le cache d'authentification de base:

document.execCommand("ClearAuthenticationCache")

Devrait retourner vrai quand cela fonctionne. Renvoie soit faux, non défini ou explose sur d'autres navigateurs.

Les nouveaux navigateurs (depuis décembre 2012: Chrome, FireFox, Safari) ont un comportement "magique". S'ils voient une demande d'authentification de base réussie avec un autre faux nom d'utilisateur (disons logout), ils effacent le cache des informations d'identification et le définissent éventuellement pour ce nouveau nom d'utilisateur faux, dont vous devez vous assurer qu'il ne s'agit pas d'un nom d'utilisateur valide pour afficher le contenu.

Un exemple de base de ceci est:

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 logoutnom d'utilisateur. 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 également en faire un bookmarklet:

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*/);


1
Cela nécessite-t-il une gestion spéciale côté serveur du logoutnom d'utilisateur et / ou de l'URL de déconnexion?
ulidtko

1
@ulidtko Non, cela ne devrait pas - tout le traitement est côté client. La seule situation qui nécessiterait une gestion spéciale est si un utilisateur appelé logoutexiste et se trouve avoir le mot de passe généré. Dans ce cas presque incroyablement rare, remplacez l'ID utilisateur par un autre qui n'existera pas sur votre système.
davidjb

2
J'ai utilisé le bookmarklet ci-dessus aujourd'hui et je travaille bien.
David Gleba

Je l'ai utilisé et cela a fonctionné pour Chrome et FF. Je n'ai eu qu'à faire un "GET" supplémentaire sur ma page logout.php pour effacer la $ _SESSION.
milieu urbain

2
Le bookmarklet fonctionne également sur Edge. Utilisez simplement avec<a href='javascript:......need*/);'>Logout</a>
Eric

21

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 déconnecter.
- redirUrl est l'URL d'une zone non protégée par mot de passe (page de réussite de déconnexion).
- vous souhaiterez peut-être augmenter le délai de redirection (actuellement 200 ms).

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


c'est la réponse la plus complète
belidzs

Y at - il raison de la $.ajaxvariante étant synchrone ( async: false) et la xmlhttpvariante étant asynchrone (l' trueen open())?
Bowi

1
Chrome utilise désormais le moteur de rendu Blink, vous devez donc passer (bowser.gecko)à (bowser.gecko || bowser.blink).
Bowi

1
Pourquoi gecko / blink utilise-t-il $.ajaxet webkit new XMLHttpRequest? Est-ce que gecko / blink ne devrait pas être capable de faire XMLHttpRequestet webkit devrait être capable de faire $.ajaxaussi? Je suis confus.
RemyNL

11

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 se déconnecte sans lui montrer à nouveau la boîte de connexion du navigateur, puis le redirige vers une page déconnectée


1
window.location = window.location.href.replace (/: \ / \ //, ': // log: out @');
sebhaase

10

Ce n'est pas directement possible avec l'authentification de base.

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 existe des «hacks» (voir les autres réponses) impliquant généralement l'utilisation de XMLHttpRequest pour envoyer une demande HTTP avec des informations d'identification incorrectes pour remplacer celles fournies à l'origine.


12
En théorie. La pratique prouve le contraire comme le montrent les autres réponses.
Stijn de Witt

2
Et comme vous pouvez également le voir dans les autres réponses, pas de manière fiable, cohérente et à sécurité intégrée!
jplandrain

5

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

C'est en fait assez simple.

Il vous suffit de visiter ce qui suit dans votre navigateur et d'utiliser des informations d'identification incorrectes: http: // nom d'utilisateur: mot de passe@votredomaine.com

Cela devrait vous déconnecter.


1
Mais l'utilisateur doit être un VRAI utilisateur, sinon j'ai reçu "401 non autorisé", mais en utilisant le bouton RETOUR, je peux continuer à travailler en tant qu'utilisateur précédemment connecté. Testé sur le serveur Web Abyss X1 (2.11.1)
user2956477

1
Réponse en double (voir ci-dessus Matthew Welborn).
Skippy le Grand Gourou

3

Tout ce dont vous avez besoin est de rediriger l'utilisateur sur une URL de déconnexion et de renvoyer une 401 Unauthorizederreur dessus. Sur la page d'erreur (qui doit être accessible sans authentification de base), vous devez fournir un lien complet vers votre page d'accueil (y compris le schéma et le nom d'hôte). L'utilisateur cliquera sur ce lien et le navigateur demandera à nouveau les informations d'identification.

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>

Je suggérerais en outre d'utiliser http_hostau 401.htmllieu de simplement host, car le premier ajoute également le numéro de port (dans le cas où un port non standard est utilisé)
Emil Koutanov

2
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
 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

Sur la base de ce que j'ai lu ci-dessus, j'ai obtenu une solution simple qui fonctionne sur n'importe quel navigateur:

1) sur votre page de déconnexion, vous appelez un ajax à votre backend de connexion. Votre backend de connexion doit accepter l'utilisateur de déconnexion. Une fois que le back-end accepte, le navigateur efface 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 d'index normal, il essaiera d'entrer automatiquement dans le système avec la "déconnexion" de l'utilisateur, cette deuxième fois, vous devez le bloquer en répondant avec 401 pour appeler la boîte de dialogue de connexion / mot de passe.

3) Il existe plusieurs façons de le faire, j'ai créé deux backends 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.


2

Je viens de tester les éléments suivants dans Chrome (79), Firefox (71) et Edge (44) et cela fonctionne très bien. Il applique la solution de script comme d'autres l'ont noté ci-dessus.

Ajoutez simplement un lien "Déconnexion" et lorsque vous cliquez dessus, renvoyez le code HTML suivant

    <div>You have been logged out. Redirecting to home...</div>    

<script>
    var XHR = new XMLHttpRequest();
    XHR.open("GET", "/Home/MyProtectedPage", true, "no user", "no password");
    XHR.send();

    setTimeout(function () {
        window.location.href = "/";
    }, 3000);
</script>

1

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+'/';
}

1

ajoutez ceci à votre application:

@app.route('/logout')
def logout():
    return ('Logout', 401, {'WWW-Authenticate': 'Basic realm="Login required"'})

préférable d'utiliser ce retour: retour ('Déconnexion', 401)
Amir Mofakhar

1

tapez chrome://restartdans la barre d'adresse et Chrome, avec toutes ses applications qui s'exécutent en arrière-plan, redémarrera et le cache de mot de passe Auth sera nettoyé.


1

Pour mémoire, il y a un nouvel en-tête de réponse HTTP appelé Clear-Site-Data. Si la réponse de votre serveur comprend un en- Clear-Site-Data: "cookies"tête, les informations d'authentification (pas seulement les cookies) doivent être supprimées. Je l'ai testé sur Chrome 77 mais cet avertissement s'affiche sur la console:

Clear-Site-Data header on 'https://localhost:9443/clear': Cleared data types:
"cookies". Clearing channel IDs and HTTP authentication cache is currently not
supported, as it breaks active network connections.

Et les informations d'authentification ne sont pas supprimées, donc cela ne fonctionne pas (pour l'instant) pour implémenter les déconnexions d'authentification de base, mais peut-être à l'avenir. N'a pas testé sur d'autres navigateurs.

Références:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Clear-Site-Data

https://www.w3.org/TR/clear-site-data/

https://github.com/w3c/webappsec-clear-site-data

https://caniuse.com/#feat=mdn-http_headers_clear-site-data_cookies


1

L'envoi https://invalid_login@hostnamefonctionne très bien partout sauf Safari sur Mac (enfin, pas vérifié Edge mais devrait fonctionner là aussi).

La déconnexion ne fonctionne pas dans Safari lorsqu'un utilisateur sélectionne «mémoriser le mot de passe» dans la fenêtre contextuelle d'authentification de base HTTP. Dans ce cas, le mot de passe est stocké dans Keychain Access (Finder> Applications> Utilities> Keychain Access (ou CMD + SPACE et tapez "Keychain Access")). L'envoi https://invalid_login@hostnamen'affecte pas l'accès au trousseau, donc avec cette case à cocher, il n'est pas possible de se déconnecter sur Safari sur Mac. Au moins, c'est comme ça que ça marche pour moi.

MacOS Mojave (10.14.6), Safari 12.1.2.

Le code ci-dessous fonctionne bien pour moi dans Firefox (73), Chrome (80) et Safari (12). Lorsqu'un utilisateur accède à une page de déconnexion, le code est exécuté et supprime les informations d'identification.

    //It should return 401, necessary for Safari only
    const logoutUrl = 'https://example.com/logout'; 
    const xmlHttp = new XMLHttpRequest();
    xmlHttp.open('POST', logoutUrl, true, 'logout');
    xmlHttp.send();

De plus, pour une raison quelconque, Safari n'enregistre pas les informations d'identification dans la fenêtre contextuelle d'authentification de base HTTP, même lorsque le «souvenir du mot de passe» est sélectionné. Les autres navigateurs le font correctement.


0
  • utiliser un identifiant de session (cookie)
  • invalider l'ID de session sur le serveur
  • N'acceptez pas les utilisateurs avec des ID de session non valides

Il est également bon d'offrir l'authentification de base comme schéma de connexion de sauvegarde lorsque les cookies ne sont pas disponibles.
bobince

0

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

-1
    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 vous redirige uniquement vers un nouvel emplacement. Pas de déconnexion.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.