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

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

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


当前回答

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

其他回答

实际上,我认为基本身份验证的目的是用于静态页面,而不是用于任何复杂的会话管理或CGI页面。

因此,当需要会话管理时,你应该设计一个经典的“登录表单”来查询用户和密码(可能也是第二个因素)。 CGI表单处理程序应该将成功的身份验证转换为服务器上记住的会话(ID)(在cookie中或作为URI的一部分)。

然后,通过使服务器(和客户端)“忘记”会话。 另一个优点是(即使加密后)用户和密码不会随每个请求一起发送到服务器(而是发送会话ID)。

如果服务器上的会话ID与执行的“最后一个动作”的时间戳相结合,则会话超时可以通过比较该时间戳与当前时间来实现: 如果时间跨度太大,则通过忘记会话ID来“超时”会话。

对无效会话的任何请求都将导致重定向到登录页面(或者如果您想让它更舒服,您可以使用“重新验证表单”再次请求密码)。

作为概念的证明,我实现了一个完全无cookie的会话管理,它完全基于URI(会话ID始终是URI的一部分)。 然而,完整的代码对于这个答案来说太长了。

当希望处理数千个并发会话时,必须特别注意性能。

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

使用会话ID (cookie) 使服务器上的会话ID失效 不接受会话id无效的用户

这在基本身份验证中是不可能直接实现的。

在HTTP规范中,服务器没有机制告诉浏览器停止发送用户已经提供的凭据。

有一些“黑客”(参见其他答案)通常涉及使用XMLHttpRequest发送带有错误凭据的HTTP请求,以覆盖最初提供的凭据。

让用户点击指向https://log:out@example.com/的链接。这将用无效的凭证覆盖现有的凭证;注销它们。

这是通过在URL中发送新的凭证来实现的。在本例中,user="log" password="out"。