質問

ユーザーが基本認証を使用している場合、ユーザーをWebサイトからログアウトさせることはできますか?

キリングセッションでは不十分です。ユーザーが認証されると、各リクエストにログイン情報が含まれるため、ユーザーは次回同じ資格情報を使用してサイトにアクセスするときに自動的にログインします。

これまでの唯一の解決策はブラウザを閉じることですが、使いやすさの観点からは受け入れられません。

役に立ちましたか?

解決

基本認証は、ログアウトを管理するようには設計されていません。できますが、完全に自動ではありません。

やらなければならないことは、ユーザーにログアウトリンクをクリックさせ、‘ 401 Unauthorized’応答として、ログインを要求する通常の401と同じレルムと同じURLフォルダーレベルを使用して送信します。

次に、間違った資格情報を入力するように指示する必要があります。空のユーザー名とパスワードを入力し、返信として“正常にログアウトしました”ページ。間違った/空の資格情報は、以前の正しい資格情報を上書きします。

要するに、ログアウトスクリプトはログインスクリプトのロジックを反転させ、ユーザーが正しい資格情報を渡していない場合にのみ成功ページを返します。

問題は、やや好奇心the盛なユーザーがパスワードを入力しないかどうかです。#8221;パスワードボックスはユーザーの承認を満たします。パスワードを自動入力しようとするパスワードマネージャーもここで邪魔になります。

コメントへの応答として追加する編集:再ログインは、わずかに異なる問題です(明らかに2段階のログアウト/ログインが必要な場合を除く)。再ログインリンクへの最初のアクセスを拒否(401)し、2番目(おそらく異なるユーザー名/パスワードを持つ)を受け入れる必要があります。これを行うにはいくつかの方法があります。 1つは、ログアウトリンクに現在のユーザー名(例:/ relogin?username)を含め、資格情報がユーザー名と一致したときに拒否することです。

他のヒント

bobinceによる回答への追加...

Ajaxを使用すると、「ログアウト」リンク/ボタンをJavaScript関数に接続できます。この関数に、不正なユーザー名とパスワードでXMLHttpRequestを送信させます。これにより401が返されます。次に、document.locationをログイン前のページに戻します。この方法では、ユーザーはログアウト中に余分なログインダイアログを表示することも、間違った資格情報を入力することを覚えておく必要もありません。

ユーザーに https:// log:out@example.com/へのリンクをクリックさせます >。これにより、既存の資格情報が無効な資格情報で上書きされます。ログアウトします。

JavaScriptで完全に実行できます:

IEには(長い間)基本認証キャッシュをクリアするための標準APIがあります:

document.execCommand("ClearAuthenticationCache")

動作する場合はtrueを返す必要があります。 false、未定義、または他のブラウザーで爆発するかのいずれかを返します。

新しいブラウザ(2012年12月現在:Chrome、FireFox、Safari)には「マジック」があります。動作。偽のユーザー名で成功の基本認証リクエストが表示された場合( logout と言います)、資格情報キャッシュをクリアし、新しい偽のユーザー名に設定します。コンテンツを表示するための有効なユーザー名ではないことを確認する必要があります。

基本的な例:

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

「非同期」上記の方法は、 logout ユーザー名を使用してAJAX呼び出しを行うことです。例:

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

ブックマークレットにすることもできます:

javascript:(function(c){var a、b ="これでログアウトされるはずです。&quot ;; 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 ="ブラウザが古すぎるか、ログアウト機能をサポートするには奇妙すぎます。すべてのウィンドウを閉じてブラウザを再起動してください。"); alert(b)})(/ *必要に応じてsafeLocationをここに渡します* /);

次の機能は、Firefox 40、Chrome 44、Opera 31、およびIE 11で動作することが確認されています。
Bowser はブラウザーの検出に使用され、jQueryも使用されます。

-secUrlは、ログアウトするパスワードで保護された領域へのURLです。
-redirUrlは、パスワードで保護されていない領域(ログアウト成功ページ)へのURLです。
-リダイレクトタイマー(現在は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);
}

これは、基本認証では直接不可能です。

サーバーのHTTP仕様には、ユーザーが既に提示した資格情報の送信を停止するようブラウザに指示するメカニズムはありません。

「ハッキング」があります(他の回答を参照)通常、XMLHttpRequestを使用して、不正な資格情報でHTTPリクエストを送信し、最初に提供された資格情報を上書きします。

これは、jQueryを使用した非常に簡単なJavascriptの例です。

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

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

このユーザーは、ブラウザーのログインボックスを再度表示せずにログアウトし、ログアウトページにリダイレクトします

実際には非常に簡単です。

ブラウザで次のページにアクセスし、間違った資格情報を使用してください。 http:// username:password@yourdomain.com

「ログアウト」する必要があります。

これは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;
}

必要なのは、ログアウトURLでユーザーをリダイレクトし、 401 Unauthorized エラーを返すことだけです。エラーページ(基本認証なしでアクセスできる必要があります)では、ホームページへの完全なリンク(スキームとホスト名を含む)を提供する必要があります。ユーザーがこのリンクをクリックすると、ブラウザが資格情報を再度要求します。

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

エラーページ /home/user/errors/401.html

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

このJavaScriptは、すべての最新バージョンのブラウザーで機能する必要があります。

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

これをアプリケーションに追加します:

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

上記で読んだ内容に基づいて、任意のブラウザーで動作する簡単なソリューションを得ました:

1)ログアウトページで、ログインバックエンドにajaxを呼び出します。ログインバックエンドはログアウトユーザーを受け入れる必要があります。バックエンドが承認すると、ブラウザは現在のユーザーをクリアし、「ログアウト」を想定します。ユーザー。

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

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

2)ユーザーが通常のインデックスファイルに戻ると、ユーザー「ログアウト」でシステムに自動的に入力しようとします。この2回目には、401で返信してブロックし、login /パスワードダイアログ。

3)それを行うには多くの方法があります。2つのログインバックエンドを作成しました。1つはログアウトユーザーを受け入れ、もう1つは受け入れません。私の通常のログインページは受け入れないものを使用し、ログアウトページはそれを受け入れるものを使用します。

  • セッションID(Cookie)を使用
  • サーバー上のセッションIDを無効にします
  • 無効なセッションIDを持つユーザーを受け入れない

最新のChromeバージョン用にmthoringのソリューションを更新しました:

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

次の方法で上記を使用してみました。

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

    // if session is not set this will redirect to login page
    if( !isset(
    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);
    }

次の方法で上記を使用してみました。

<*>

ただし、新しい場所にリダイレクトされるだけです。ログアウトなし。

SESSION['user']) ) { header("Location: index.php"); exit; } // select loggedin users detail $res=mysql_query("SELECT * FROM users WHERE userId=".
    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);
    }

次の方法で上記を使用してみました。

<*>

ただし、新しい場所にリダイレクトされるだけです。ログアウトなし。

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

ただし、新しい場所にリダイレクトされるだけです。ログアウトなし。

バックグラウンドで実行されているすべてのアプリで、アドレスバーとchromeに

type chrome:// restart と入力すると、再起動し、認証パスワードキャッシュが消去されます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top