Frage

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

Sitzung zu töten ist nicht genug, da, sobald Benutzer authentifiziert ist, jede Anfrage Anmeldedaten enthält, so Benutzer werden in nächstem Mal, wenn er / sie Zugriff auf die Website mit den gleichen Anmeldeinformationen automatisch protokollieren.

Die einzige Lösung, so weit ist Browser zu schließen, aber das ist nicht akzeptabel, aus der Usability-Sicht.

War es hilfreich?

Lösung

Basis-Authentifizierung wurde nicht abzumelden verwalten konzipiert. Sie können es tun, aber nicht vollständig automatisch.

Was müssen Sie tun, ist der Benutzer einen Logout-Link klicken, und ein ‚401 Unauthorized‘ als Antwort zu senden, den gleichen Bereich mit und auf der gleichen URL Ordnerebene wie die normalen 401 ein Anmelde senden anfordern.

Sie müssen neben Eingang falscher Anmeldeinformationen gerichtet werden, zum Beispiel. „Erfolgreich abgemeldet Sie haben“ Seite ein leerer Benutzername und Kennwort, und als Antwort senden Sie zurück. Die falschen / leeren Anmeldeinformationen werden dann die vorherigen richtigen Anmeldeinformationen überschreiben.

Kurz gesagt, der Logout-Skript invertiert die Logik des Login-Skripts, nur den Erfolg Seite zurückkehren, wenn der Benutzer nicht die richtigen Anmeldeinformationen übergeben.

Die Frage ist, ob das etwas merkwürdig „Geben Sie nicht Ihr Passwort“ Passwort-Box wird die Benutzerakzeptanz erfüllen. Passwort-Manager, die auch hier in der Quere kommen kann versuchen, das Passwort automatisch füllen.

In Antwort hinzufügen Kommentar: re-Login ein etwas anderes Problem ist (es sei denn, Sie ein zweistufiger logout / login offensichtlich erforderlich). Sie müssen (401) den ersten Versuch, lehnen die Relogin Link zuzugreifen, als die zweite akzeptieren (was vermutlich einen anderen Benutzernamen / Passwort hat). Es gibt ein paar Möglichkeiten, wie Sie dies tun könnte. Eine wäre, den aktuellen Benutzernamen in den Logout-Link enthalten (zB. / Relogin? Benutzername), und ablehnen, wenn die Anmeldeinformationen den Benutzernamen übereinstimmen.

Andere Tipps

Eine Ergänzung zu der Antwort von bobince ...

Mit Ajax Sie Ihren 'Logout' Link / Button verdrahtet auf eine Javascript-Funktion haben können. Lassen Sie sich diese Funktion, um die XMLHttpRequest mit einem schlechten Benutzernamen und ein Passwort. Dies sollte ein 401. Dann setzen document.location zurück zur Pre-Login-Seite zurück. Auf diese Weise wird der Benutzer nie den zusätzlichen Login-Dialog beim Logout sieht, noch müssen bedenken, in schlechten Anmeldeinformationen zu setzen.

Haben Sie den Benutzer klicken Sie auf einen Link https: // log: out@example.com/ . Das wird bestehende Zugangsdaten mit ungültigen überschreiben; Anmeldung sie aus.

Sie können es ganz in JavaScript:

IE hat (für eine lange Zeit) Standard-API für Basic Authentication Cache zu löschen:

document.execCommand("ClearAuthenticationCache")

Wenn true zurück, wenn es funktioniert. Gibt entweder falsch, nicht definiert oder sprengt in anderen Browsern.

Neuer Browser (Stand Dezember 2012: Chrome, Firefox, Safari) "Magie" Verhalten. Wenn sie ein erfolgreich Grund Auth Anfrage mit jeder falschen anderen Benutzernamen sehen (wir logout sagen) sie löschen die Credentials Cache und es möglicherweise für diese neue gefälschte Benutzernamen festgelegt, die Sie sicher machen müssen, ist kein gültige Benutzername für Inhalte.

Grund 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 „asynchron“ Art und Weise der oben zu tun ist, einen AJAX-Aufruf unter Verwendung des logout Benutzername zu tun. 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 ein Bookmarklet machen auch:

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

Die folgende Funktion wird bestätigt, arbeitet für Firefox 40, Chrome 44, Opera 31 und IE 11.
Bowser für Browser-Erkennung verwendet wird, wird jQuery verwendet.
- secUrl ist die URL zu einem passwortgeschützten Bereich, aus dem sich abzumelden
. - redirurl ist die URL zu einem nicht passwortgeschützten Bereich (logout Erfolg Seite).
-. Sie könnten wollen die Umleitung Timer (zur Zeit 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 nicht direkt möglich, bei Basic-Authentifizierung.

Es gibt keinen Mechanismus in der HTTP-Spezifikation für den Server des Browser mitzuteilen, die Berechtigungsnachweise mehr zu senden, dass der Benutzer bereits vorgestellt.

Es gibt „Hacks“ (andere Antworten sehen) in der Regel unter Verwendung von XMLHttpRequest denen eine HTTP-Anforderung mit falschen Anmeldeinformationen zu senden, um die zu überschreiben ursprünglich geliefert.

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

Dieses Protokoll Benutzer, ohne ihm den Browser Log-in-Box wieder zeigt, dann umleiten ihn ein abgemeldet Seite

Es ist eigentlich ziemlich einfach.

Besuchen Sie einfach die folgenden in Ihrem Browser und verwenden falsche Anmeldeinformationen: http: // username: password@yourdomain.com

Das sollte "log dich aus".

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

Alles, was Sie brauchen, ist Benutzer auf einige Abmelde URL umleiten und 401 Unauthorized Fehler auf ihn zurück. Auf Fehlerseite (die ohne grundlegende auth zugänglich sein müssen) benötigen Sie einen vollständigen Link zu Ihrer Homepage zur Verfügung zu stellen (einschließlich Schema und Hostnamen). Benutzer klicken auf diesen Link und Browser wird wieder für Anmeldeinformationen fragen.

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>

Dieses JavaScript muss für alles neueste Version Browser 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+'/';
}

Fügen Sie diese zu Ihrer Anwendung:

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

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

1) auf Sie Seite abzumelden Sie eine Ajax zu Ihrem Login-Rückruf Ende. Ihre Login-Backend muss Logout Benutzer akzeptieren. Sobald das hintere Ende akzeptieren, deaktivieren Sie das Browser den aktuellen Benutzer und nimmt den „Logout“ user.

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

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

2) Nun, wenn der Benutzer wieder in die normalen Indexdatei muss es automatische Eingabe in dem System mit dem Benutzer versuchen wird, „Logout“, auf dieses zweite Mal, wenn Sie es durch Antwort mit 401 blockieren muss das Login / Passwort aufrufe Dialog.

3) Es gibt viele Möglichkeiten, das zu tun, habe ich zwei Login Enden zurück, eine, die den Logout-Benutzer und eine, die nicht der Fall ist akzeptiert. Meine normale Login-Seite die eine, die nicht, meine Logout-Seite die man verwenden akzeptiert, dass sie akzeptiert.

  • verwenden, um eine Session-ID (Cookie)
  • ungültig macht die Session-ID auf dem Server
  • Akzeptieren Sie keine Benutzer mit ungültigen Session-IDs

I mthoring-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);
}
    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, die oben in der folgenden Art und Weise verwendet wird.

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

Aber es leitet nur Sie neue Position. Keine logout.

Typ chrome://restart in der Adressleiste und Chrom, mit all seinen Anwendungen, die im Hintergrund ausgeführt wird, wird neu gestartet und die Auth Passwort-Cache gereinigt werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top