Wie kann ich Benutzer mithilfe der BASIC-Authentifizierung von der Website abmelden?


278

Ist es möglich, Benutzer von einer Website abzumelden, wenn er die Basisauthentifizierung verwendet?

Das Beenden einer Sitzung reicht nicht aus, da jede Anforderung nach der Authentifizierung des Benutzers Anmeldeinformationen enthält, sodass der Benutzer beim nächsten Zugriff auf die Site mit denselben Anmeldeinformationen automatisch angemeldet wird.

Die einzige Lösung besteht bisher darin, den Browser zu schließen. Dies ist jedoch unter dem Gesichtspunkt der Benutzerfreundlichkeit nicht akzeptabel.


1
Nur neugierig. Warum willst du das tun?
DOK

17
Um sich als anderer Benutzer anmelden zu können.
Marko

16
@DOK - Es ist eine Standard-Social-Hacking-Sache: Benutzer sollten sich abmelden können, während sie ihren Browser offen lassen. Angenommen, einer Ihrer Benutzer greift auf einem öffentlichen Computer auf die Site zu? Sie müssen sich explizit abmelden, damit der nächste Benutzer nicht auf die Site zugreifen kann.
Keith

@DOK Es gibt auch das Problem, dass der Benutzer sich nicht von der Site abmelden kann. Der Server kann das Autorisierungscookie und sogar das Sitzungscookie löschen. Wenn der Browser die /Seite lädt , werden sie automatisch wieder angemeldet.
Ian Boyd

Ich verwende die Methode, die eine gefälschte Anfrage zum Abmelden sendet, aber sie sperrt den Benutzer im Kunden, da es eine strikte Einschränkung gibt, dass die dreimalige Anmeldung in AD fehlgeschlagen ist. Schlagen Sie daher vor, diese Methode mit Vorsicht zu verwenden (senden Sie eine gefälschte Anfrage).
Qianchao Pan

Antworten:


170

Die Standardauthentifizierung wurde nicht zum Verwalten der Abmeldung entwickelt. Sie können es tun, aber nicht ganz automatisch.

Was Sie tun müssen, ist, dass der Benutzer auf einen Abmeldelink klickt und als Antwort eine "401 Unauthorized" sendet, wobei er denselben Bereich und dieselbe URL-Ordnerebene wie die normale 401 verwendet, die Sie senden, um eine Anmeldung anzufordern.

Sie müssen angewiesen werden, als nächstes falsche Anmeldeinformationen einzugeben, z. einen leeren Benutzernamen und ein leeres Passwort, und als Antwort senden Sie eine Seite "Sie haben sich erfolgreich abgemeldet" zurück. Die falschen / leeren Anmeldeinformationen überschreiben dann die vorherigen korrekten Anmeldeinformationen.

Kurz gesagt, das Abmeldeskript kehrt die Logik des Anmeldeskripts um und gibt die Erfolgsseite nur zurück, wenn der Benutzer nicht die richtigen Anmeldeinformationen übergibt.

Die Frage ist, ob das etwas merkwürdige Passwortfeld "Geben Sie Ihr Passwort nicht ein" die Akzeptanz beim Benutzer findet. Kennwortmanager, die versuchen, das Kennwort automatisch einzugeben, können hier ebenfalls im Weg stehen.

Bearbeiten, um als Antwort auf einen Kommentar hinzuzufügen: Die erneute Anmeldung ist ein etwas anderes Problem (es sei denn, Sie benötigen offensichtlich eine zweistufige Abmeldung / Anmeldung). Sie müssen den ersten Versuch, auf den Relogin-Link zuzugreifen, ablehnen (401), als den zweiten zu akzeptieren (der vermutlich einen anderen Benutzernamen / ein anderes Passwort hat). Es gibt einige Möglichkeiten, wie Sie dies tun können. Eine Möglichkeit besteht darin, den aktuellen Benutzernamen in den Abmeldelink aufzunehmen (z. B. / relogin? Benutzername) und abzulehnen, wenn die Anmeldeinformationen mit dem Benutzernamen übereinstimmen.


2
Ich werde diesen Ansatz versuchen. Der Abmeldepunkt (in diesem Fall) besteht darin, dem Benutzer zu ermöglichen, sich als anderer Benutzer anzumelden. Dies ist also eine durchaus akzeptable Lösung. Für das automatische Ausfüllen des Passworts ist es Sache des Benutzers, ob er es verwendet oder nicht. Danke
Marko

Ist das noch der einzige Weg? Ich habe eine ASP.Net MVC- und jQuery-Implementierung durchgeführt, die funktioniert, bin aber immer noch nicht zufrieden damit: stackoverflow.com/questions/6277919
Keith

@Keith: Immer noch nur diese und die Antwort von systemPAUSE (die nicht in allen Browsern funktioniert, aber flüssiger ist als der manuelle Ansatz, wenn sie funktioniert).
Bobince

16
Das W3C ist in der HTML-Spezifikation so aktiv. Aber die HTTP-Spezifikation leidet. W3C hätte dieses Problem vor etwa zwei Jahrzehnten beheben sollen. Mit der zunehmenden Nutzung von REST-Diensten ist eine robuste native Authentifizierungsmethode erforderlich.
Dojo

9
Dies scheint beim Durchsuchen von Chrome 46 auf localhost nicht richtig zu funktionieren. Chrome scheint sowohl das alte (korrekte) als auch das von Ihnen angegebene neue Passwort beizubehalten. Nach dem Navigieren zur Abmeldeseite verwendet Chrome das neue Kennwort korrekt, BIS ES AUF EINER SEITE AUF IHRER WEBSITE NICHT AUTORISIERT IST. Nach dem ersten 401 kehrt Chrome zum alten (korrekten) Kennwort zurück. Es hat also das Passwort anscheinend überhaupt nicht gelöscht.
Vancan1ty

196

Eine Ergänzung zur Antwort von Bobince ...

Mit Ajax können Sie Ihren Link / Button "Abmelden" mit einer Javascript-Funktion verbinden. Lassen Sie diese Funktion die XMLHttpRequest mit einem falschen Benutzernamen und Passwort senden. Dies sollte einen 401 zurückgeben. Setzen Sie dann document.location zurück auf die Voranmeldeseite. Auf diese Weise wird dem Benutzer während der Abmeldung niemals der zusätzliche Anmeldedialog angezeigt, und er muss auch nicht daran denken, falsche Anmeldeinformationen einzugeben.


12
Guter Hack, wenn der Benutzer falsche Anmeldeinformationen manuell eingibt, ist dies für die meisten Webanwendungen wahrscheinlich nicht akzeptabel.
BillMan

1
Stellen Sie einfach sicher, dass XMLHttpRequest nicht asynchron eingestellt ist. Andernfalls erfolgt die Umleitung über möglicherweise, bevor die Abmeldeanforderung abgeschlossen ist.
Davidjb

5
Sie können den gleichen Trick auch für die Anmeldung verwenden. Auf diese Weise können Sie den Anmeldedialog anpassen, ohne die Authentifizierungsmethode des Servers ändern zu müssen. Dieser Artikel gibt einige gute Ideen: http://www.peej.co.uk/articles/http-auth-with-html-forms.html
Stijn de Witt

1
@davidjb Da synchrone Anforderungen jetzt als veraltet gelten, besteht eine alternative Lösung darin, den Benutzer beim Rückruf der asynchronen Anforderung umzuleiten.
Hayden Schiff

1
David: Chrome erlaubt dies jetzt für XHRs, und ich kann bestätigen, dass es immer noch in Chrome Canary funktioniert. bugs.chromium.org/p/chromium/issues/detail?id=435547
CpnCrunch

192

Lassen Sie den Benutzer auf einen Link zu https: // log: out@example.com/ klicken . Dadurch werden vorhandene Anmeldeinformationen mit ungültigen überschrieben. Abmelden.


19
Warum bekommt dieser nicht mehr Upvotes? Scheint mir eine einfache und funktionierende Lösung zu sein. Gibt es bekannte Probleme mit diesem Ansatz?
Amöbe

35
Dies würde in Chrome nicht mehr funktionieren, da aus Sicherheitsgründen Anmeldeinformationen in einer URL ignoriert werden.
Thom

5
Das hat bei mir funktioniert :) Ich verwende Chrome Version 32.0.1700.102
abottoni

6
Problem: Verwenden der Version 39.0 von Chrome. Wenn ich über diese Methode auf den Abmeldelink klicke, merkt sich Chrome die fehlerhaften Anmeldeinformationen und fordert bei jedem Laden der Seite zur Eingabe neuer Anmeldeinformationen auf, bis ich ohne angegebene Anmeldeinformationen zu example.com gehe Chromspeicher löschen.
Scott

4
Hallo, ich kann es nicht für https in Chrome verwenden.
Thienkhoi Tran

67

Sie können dies vollständig in JavaScript tun:

IE verfügt (seit langem) über eine Standard-API zum Löschen des Cache für die Standardauthentifizierung:

document.execCommand("ClearAuthenticationCache")

Sollte true zurückgeben, wenn es funktioniert. Gibt entweder false, undefined oder explodiert in anderen Browsern zurück.

Neue Browser (Stand Dezember 2012: Chrome, FireFox, Safari) verhalten sich "magisch". Wenn sie eine erfolgreiche grundlegende Authentifizierungsanforderung mit einem falschen anderen Benutzernamen sehen (sagen wir logout), löschen sie den Cache für Anmeldeinformationen und legen ihn möglicherweise für diesen neuen falschen Benutzernamen fest, den Sie sicherstellen müssen, dass es sich nicht um einen gültigen Benutzernamen zum Anzeigen von Inhalten handelt.

Grundlegendes Beispiel dafür ist:

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

Eine "asynchrone" Möglichkeit, dies zu tun, besteht darin, einen AJAX-Aufruf unter Verwendung des logoutBenutzernamens durchzuführen. Beispiel:

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

Sie können es auch zu einem Lesezeichen machen:

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
Erfordert dies eine spezielle serverseitige Behandlung des logoutBenutzernamens und / oder der Abmelde-URL?
Ulidtko

1
@ulidtko Nein, sollte es nicht - alles Handling ist clientseitig. Die einzige Situation, die eine besondere Behandlung erfordern würde, besteht darin, dass ein angerufener Benutzer logoutexistiert und das generierte Passwort hat. Ändern Sie in diesem fast unmöglich seltenen Fall die Benutzer-ID in eine ID, die in Ihrem System nicht vorhanden ist.
Davidjb

2
Ich habe heute das oben genannte Lesezeichen verwendet und arbeite gut.
David Gleba

Ich habe dies verwendet und es hat für Chrome und FF funktioniert. Ich musste nur ein zusätzliches "GET" auf meiner logout.php-Seite ausführen, um die $ _SESSION zu löschen.
Urban

2
Das Lesezeichen funktioniert auch mit Edge. Einfach verwenden mit<a href='javascript:......need*/);'>Logout</a>
Eric

21

Die folgende Funktion wurde für Firefox 40, Chrome 44, Opera 31 und IE 11 bestätigt.
Bowser wird zur Browsererkennung verwendet, jQuery wird ebenfalls verwendet.

- secUrl ist die URL zu einem kennwortgeschützten Bereich, von dem aus Sie sich abmelden können.
- redirUrl ist die URL zu einem nicht kennwortgeschützten Bereich (Abmeldungserfolgsseite).
- Möglicherweise möchten Sie den Umleitungszeitgeber (derzeit 200 ms) erhöhen.

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


Dies ist die umfassendste Antwort
belidzs

Gibt es einen Grund dafür, dass die $.ajaxVariante synchron ( async: false) und die xmlhttpVariante asynchron ( truein open()) ist?
Bowi

1
Chrome nutzt nun die Rendering - Engine Blink, so dass Sie sich ändern müssen (bowser.gecko)zu (bowser.gecko || bowser.blink).
Bowi

1
Warum wird Gecko / Blink $.ajaxund Webkit verwendet new XMLHttpRequest? Sollte Gecko / Blink nicht dazu in der Lage sein XMLHttpRequestund Webkit auch dazu $.ajax? Ich bin verwirrt.
RemyNL

11

Hier ist ein sehr einfaches Javascript-Beispiel mit jQuery:

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

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

Dieser Benutzer meldet sich ab, ohne ihm das Anmeldefeld des Browsers erneut anzuzeigen, und leitet ihn dann auf eine abgemeldete Seite weiter


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

10

Dies ist mit der Basisauthentifizierung nicht direkt möglich.

In der HTTP-Spezifikation gibt es keinen Mechanismus für den Server, der den Browser anweist, das Senden der vom Benutzer bereits vorgelegten Anmeldeinformationen zu beenden.

Es gibt "Hacks" (siehe andere Antworten), bei denen normalerweise XMLHttpRequest zum Senden einer HTTP-Anforderung mit falschen Anmeldeinformationen verwendet wird, um die ursprünglich angegebenen zu überschreiben.


12
In der Theorie. Die Praxis beweist das Gegenteil, wie aus den anderen Antworten hervorgeht.
Stijn de Witt

2
Und wie Sie auch aus den anderen Antworten ersehen können, nicht zuverlässig, konsistent und ausfallsicher!
Jplandrain

5

Dies funktioniert für 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

Es ist eigentlich ziemlich einfach.

Besuchen Sie einfach Folgendes in Ihrem Browser und verwenden Sie falsche Anmeldeinformationen: http: // Benutzername: Passwort@IhreDomain.com

Das sollte "dich abmelden".


1
Der Benutzer muss jedoch ein ECHTER Benutzer sein, ansonsten habe ich "401 Unauthorized" erhalten, aber mit der Schaltfläche BACK kann ich als zuvor angemeldeter Benutzer weiterarbeiten. Getestet auf Abyss Webserver X1 (2.11.1)
user2956477

1
Doppelte Antwort (siehe Matthew Welborns oben).
Skippy le Grand Gourou

3

Sie müssen lediglich den Benutzer auf eine Abmelde-URL umleiten und einen 401 UnauthorizedFehler zurückgeben. Auf der Fehlerseite (auf die ohne grundlegende Authentifizierung zugegriffen werden muss) müssen Sie einen vollständigen Link zu Ihrer Homepage (einschließlich Schema und Hostname) angeben. Der Benutzer klickt auf diesen Link und der Browser fragt erneut nach Anmeldeinformationen.

Beispiel für 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;
}

Fehlerseite /home/user/errors/401.html:

<!DOCTYPE html>
<p>You're not authorised. <a href="<!--# echo var="scheme" -->://<!--# echo var="host" -->/">Login</a>.</p>

Ich würde weiter vorschlagen, http_hostin 401.htmlstatt einfach zu verwenden host, da ersterer auch die Portnummer hinzufügt (falls ein nicht standardmäßiger Port verwendet wird)
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

Basierend auf dem, was ich oben gelesen habe, habe ich eine einfache Lösung erhalten, die in jedem Browser funktioniert:

1) Auf Ihrer Abmeldeseite rufen Sie einen Ajax für Ihr Login-Backend auf. Ihr Login-Backend muss den Logout-Benutzer akzeptieren. Sobald das Back-End akzeptiert, löscht der Browser den aktuellen Benutzer und übernimmt den Benutzer "Abmelden".

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

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

2) Wenn der Benutzer nun zur normalen Indexdatei zurückgekehrt ist, versucht er, automatisch mit dem Benutzer "Abmelden" in das System einzutreten. Beim zweiten Mal müssen Sie diese durch Antworten mit 401 blockieren, um den Anmelde- / Kennwortdialog aufzurufen.

3) Es gibt viele Möglichkeiten, dies zu tun. Ich habe zwei Login-Backends erstellt, eines, das den Logout-Benutzer akzeptiert, und eines, das dies nicht tut. Meine normale Anmeldeseite verwendet diejenige, die nicht akzeptiert, meine Abmeldeseite verwendet diejenige, die sie akzeptiert.


2

Ich habe gerade Folgendes in Chrome (79), Firefox (71) und Edge (44) getestet und es funktioniert einwandfrei. Es wendet die Skriptlösung wie die oben genannten an.

Fügen Sie einfach einen "Abmelden" -Link hinzu und geben Sie beim Klicken den folgenden HTML-Code zurück

    <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

Dieses JavaScript muss für alle Browser der neuesten Version funktionieren:

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

Fügen Sie dies Ihrer Anwendung hinzu:

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

Verwenden Sie diese Rückgabe besser: return ('Logout', 401)
Amir Mofakhar

1

Geben Sie chrome://restartdie Adressleiste ein und Chrome mit all seinen Apps, die im Hintergrund ausgeführt werden, wird neu gestartet und der Auth-Passwort-Cache wird bereinigt.


1

Nur für den Datensatz gibt es einen neuen HTTP-Antwortheader namens Clear-Site-Data. Wenn Ihre Serverantwort einen Clear-Site-Data: "cookies"Header enthält, sollten die Authentifizierungsdaten (nicht nur Cookies) entfernt werden. Ich habe es auf Chrome 77 getestet, aber diese Warnung wird auf der Konsole angezeigt:

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.

Und die Anmeldeinformationen für die Authentifizierung werden nicht entfernt, sodass dies (vorerst) nicht zum Implementieren grundlegender Authentifizierungsabmeldungen funktioniert, aber möglicherweise in Zukunft. Nicht in anderen Browsern getestet.

Verweise:

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

Das Senden https://invalid_login@hostnamefunktioniert überall gut, außer bei Safari auf dem Mac (naja, Edge ist nicht aktiviert, sollte aber auch dort funktionieren).

Die Abmeldung funktioniert in Safari nicht, wenn ein Benutzer im Popup "HTTP-Basisauthentifizierung" die Option "Kennwort speichern" auswählt. In diesem Fall wird das Kennwort unter Schlüsselbundzugriff (Finder> Anwendungen> Dienstprogramme> Schlüsselbundzugriff (oder CMD + SPACE und geben Sie "Schlüsselbundzugriff")) gespeichert. Sendenhttps://invalid_login@hostname hat keinen Einfluss auf den Schlüsselbundzugriff. Mit diesem Kontrollkästchen ist es daher nicht möglich, sich bei Safari auf dem Mac abzumelden. Zumindest funktioniert es bei mir so.

MacOS Mojave (10.14.6), Safari 12.1.2.

Der folgende Code funktioniert gut für mich in Firefox (73), Chrome (80) und Safari (12). Wenn ein Benutzer zu einer Abmeldeseite navigiert, wird der Code ausgeführt und die Anmeldeinformationen werden gelöscht.

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

Aus irgendeinem Grund speichert Safari keine Anmeldeinformationen im Popup-Fenster "HTTP Basic Authentication", selbst wenn "Kennwort speichern" ausgewählt ist. Die anderen Browser machen das richtig.


0
  • Verwenden Sie eine Sitzungs-ID (Cookie).
  • Die Sitzungs-ID auf dem Server wird ungültig
  • Akzeptieren Sie keine Benutzer mit ungültigen Sitzungs-IDs

Es ist auch gut, die Standardauthentifizierung als Backup-Anmeldeschema anzubieten, wenn keine Cookies verfügbar sind.
Bobince

0

Ich habe die Lösung von mthoring für moderne Chrome-Versionen aktualisiert:

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

Ich habe versucht, das oben genannte auf folgende Weise zu verwenden.

?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(); ?>

Es leitet Sie jedoch nur an einen neuen Ort weiter. Keine Abmeldung.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.