是否有可能注销用户从一个网站,如果他是使用基本身份验证?

杀死会话是不够的,因为一旦用户通过身份验证,每个请求都包含登录信息,因此用户下次使用相同的凭据访问站点时将自动登录。

目前唯一的解决方案是关闭浏览器,但从可用性的角度来看,这是不可接受的。


当前回答

在地址栏中输入chrome://restart, chrome和所有在后台运行的应用程序将重新启动,Auth密码缓存将被清除。

其他回答

bobince对这个问题的补充回答是…

使用Ajax,您可以将“注销”链接/按钮连接到Javascript函数。让这个函数发送带有错误用户名和密码的XMLHttpRequest。这应该会得到401。然后设置文档。位置返回到预登录页面。这样,用户将永远不会在注销期间看到额外的登录对话框,也不必记得输入错误的凭据。

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

发送https://invalid_login@hostname在任何地方都可以工作,除了Mac上的Safari(好吧,没有勾选Edge,但也应该工作)。

当用户在HTTP基本身份验证弹出框中选择“记住密码”时,Safari中的注销不工作。在这种情况下,密码存储在Keychain Access (Finder > Applications > Utilities > Keychain Access(或CMD+SPACE并键入“Keychain Access”))中。发送https://invalid_login@hostname不会影响钥匙链访问,所以这个复选框不可能在Mac上的Safari上注销。至少它是如何为我工作的。

MacOS Mojave (10.14.6), Safari 12.1.2。

下面的代码在Firefox(73)、Chrome(80)和Safari(12)中运行良好。当用户导航到登出页面时,执行代码并删除凭据。

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

此外,由于某些原因,Safari不会在HTTP基本身份验证弹出框中保存凭据,即使选择了“记住密码”。其他浏览器可以正确地做到这一点。

为了记录,有一个新的HTTP响应头叫做Clear-Site-Data。如果你的服务器回复包含一个Clear-Site-Data: "cookies"头,那么身份验证凭证(不仅仅是cookies)应该被删除。我在Chrome 77上测试了它,但控制台显示了这个警告:

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.

并且认证凭证没有被删除,所以这不能(目前)实现基本的认证注销,但也许将来会。没有在其他浏览器上测试。

引用:

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

我刚刚在Chrome(79)、Firefox(71)和Edge(44)上测试了以下程序,效果良好。它应用上面提到的脚本解决方案。

只需添加一个“注销”链接,点击返回以下html

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