it-swarm.com.de

Wie melde ich mich mit der BASIC-Authentifizierung von einer Website ab?

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

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

Bisher ist die einzige Lösung das Schließen des Browsers, was jedoch aus Sicht der Benutzerfreundlichkeit nicht akzeptabel ist.

251
Marko

Die Standardauthentifizierung war nicht für die Verwaltung der Abmeldung konzipiert. Sie können es tun, aber nicht ganz automatisch.

Sie müssen den Benutzer dazu bringen, auf einen Abmeldelink zu klicken und als Antwort eine "401 Unauthorized" (401 nicht autorisiert) zu senden. Dabei müssen Sie denselben Bereich und dieselbe URL-Ordnerebene wie bei der normalen 401 verwenden, die Sie senden, um eine Anmeldung anzufordern.

Sie müssen angewiesen werden, als nächstes falsche Anmeldeinformationen einzugeben, z. Geben Sie einen leeren Benutzernamen und ein leeres Kennwort ein und senden Sie als Antwort eine Seite mit dem Titel "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 dann zurück, wenn der Benutzer nicht die richtigen Anmeldeinformationen weitergibt.

Die Frage ist, ob das etwas merkwürdige Kennwortfeld "Geben Sie Ihr Kennwort nicht ein" die Akzeptanz durch den Benutzer erreicht. Auch Passwortmanager, die versuchen, das Passwort automatisch auszufüllen, können hier stören.

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 wäre, den aktuellen Benutzernamen in den Abmeldelink aufzunehmen (z. B./relogin? Username) und abzulehnen, wenn die Anmeldeinformationen mit dem Benutzernamen übereinstimmen.

160
bobince

Eine Ergänzung zur Antwort von Bobince ...

Mit Ajax können Sie Ihren 'Logout'-Link/Button mit einer Javascript-Funktion verbinden. Lassen Sie diese Funktion den 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 des Abmeldevorgangs weder das zusätzliche Anmeldedialogfeld angezeigt, noch muss er daran denken, falsche Anmeldeinformationen einzugeben.

192
system PAUSE

Lassen Sie den Benutzer auf einen Link zu https: // log: [email protected]/ klicken. Dadurch werden vorhandene Anmeldeinformationen mit ungültigen überschrieben. logge sie aus.

177
Matthew Welborn

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

IE hat (seit langem) Standard-API zum Löschen des Cache für die Basisauthentifizierung:

document.execCommand("ClearAuthenticationCache")

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

Neue Browser (ab Dezember 2012: Chrome, FireFox, Safari) verhalten sich "magisch". Wenn eine erfolgreiche grundlegende Authentifizierungsanforderung mit einem falschen anderen Benutzernamen angezeigt wird (sagen wir logout), wird der Cache für Anmeldeinformationen geleert und möglicherweise für diesen neuen falschen Benutzernamen festgelegt, den Sie benötigen Stellen Sie sicher, dass kein gültiger Benutzername zum Anzeigen von Inhalten angegeben ist.

Ein 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:[email protected]')

Eine "asynchrone" Methode ist der Aufruf von AJAX unter Verwendung des Benutzernamens logout. 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*/);

63
ddotsenko

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

- secUrl ist die URL zu einem passwortgeschützten Bereich, von dem aus Sie sich abmelden können.
- redirUrl ist die URL zu einem nicht passwortgeschützten Bereich (Logout-Erfolgsseite).
- Möglicherweise möchten Sie den Umleitungs-Timer (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);
}
18
mthoring

Hier ist ein sehr einfaches Javascript-Beispiel mit jQuery:

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

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

Dieser Benutzer wird abgemeldet, ohne dass ihm das Anmeldefeld des Browsers erneut angezeigt wird. Anschließend wird er auf eine abgemeldete Seite umgeleitet

11
Romuald Brunet

Dies ist mit Basic-Authentication nicht direkt möglich.

In der HTTP-Spezifikation gibt es keinen Mechanismus, mit dem der Server den Browser anweist, die vom Benutzer bereits vorgelegten Anmeldeinformationen nicht mehr zu senden.

Es gibt "Hacks" (siehe andere Antworten), bei denen in der Regel XMLHttpRequest verwendet wird, um eine HTTP-Anforderung mit falschen Anmeldeinformationen zu senden und die ursprünglich angegebenen zu überschreiben.

10
Alnitak

Es ist eigentlich ziemlich einfach.

Besuchen Sie einfach das Folgende in Ihrem Browser und verwenden Sie falsche Anmeldeinformationen: http: // Benutzername: [email protected]

Das sollte "dich ausloggen".

6
Chiedo

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
Claudio

Sie müssen den Benutzer lediglich auf eine Abmelde-URL umleiten und den Fehler 401 Unauthorized Darauf zurückgeben. Auf der Fehlerseite (auf die ohne grundlegende Berechtigung zugegriffen werden muss) müssen Sie einen vollständigen Link zu Ihrer Homepage angeben (einschließlich Schema und Hostname). 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>
2
Envek
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
Charlie
 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, die in jedem Browser funktioniert:

1) Auf Ihrer Abmeldeseite rufen Sie ein 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 zur normalen Indexdatei zurückgekehrt ist, versucht er automatisch, sich mit dem Benutzer "logout" in das System einzuloggen. Beim zweiten Mal müssen Sie ihn 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, eine, die den Logout-Benutzer akzeptiert, und eine, die dies nicht tut. Meine normale Anmeldeseite verwendet diejenige, die sie nicht akzeptiert, meine Abmeldeseite verwendet diejenige, die sie akzeptiert.

1
Foad

Dieses JavaScript muss für alle aktuellen Browser-Versionen 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 = /*@[email protected]*/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:[email protected]'+Host+'/';
}
1
Amit Shah

fügen Sie dies zu Ihrer Bewerbung hinzu:

@app.route('/logout')
def logout():
    return ('Logout', 401, {'WWW-Authenticate': 'Basic realm="Login required"'})
1
Amir Mofakhar
  • verwenden Sie eine Sitzungs-ID (Cookie)
  • die Sitzungs-ID auf dem Server ungültig machen
  • Akzeptieren Sie keine Benutzer mit ungültigen Sitzungs-IDs
0
Tomalak

Ich habe mthorings Lösung 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);
}
0
Max
    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);
    }</ code>

Ich habe versucht, die oben genannten wie folgt 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(); ?>

Sie werden jedoch nur an einen neuen Standort weitergeleitet. Keine Abmeldung.

0

art chrome://restart in der Adressleiste und Chrome mit allen im Hintergrund ausgeführten Apps werden neu gestartet und der Auth Password Cache wird geleert.

0
Ali