如何使用BASIC身份验证从Web站点注销用户?

Mar*_*rko 259 authentication http basic-authentication

如果用户使用基本身份验证,是否可以从网站注销用户?

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

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

sys*_*USE 193

除了答案之外...

使用Ajax,您可以将"Logout"链接/按钮连接到Javascript函数.让此函数使用错误的用户名和密码发送XMLHttpRequest.这应该返回401.然后将document.location设置回登录前页面.这样,用户在注销时将永远不会看到额外的登录对话框,也不必记得输入错误的凭据.

  • 对于大多数Web应用程序来说,用户手动输入错误的凭据可能是不可接受的. (12认同)
  • 您也可以使用相同的技巧进行登录.这样,您可以自定义登录对话框,而无需更改服务器的身份验证方法.本文提供了一些好主意:[http://www.peej.co.uk/articles/http-auth-with-html-forms.html](http://www.peej.co.uk/articles/http -auth-与-HTML-forms.html) (5认同)
  • @davidjb 由于现在认为同步请求已被弃用,因此替代解决方案可能是在异步请求的回调中重定向用户。 (2认同)

小智 184

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

  • 这将不再适用于Chrome,出于安全考虑,Chrome会忽略网址中的凭据. (31认同)
  • 为什么这个没有得到更多的赞成?对我来说,这似乎是一个简单而有效的解决方案.这种方法有任何已知问题吗? (19认同)
  • 问题:使用版本39.0的chrome,当我通过此方法点击退出链接时,Chrome会记住错误的登录凭据,并在每次加载页面时提示输入新的登录凭据,直到我转到https://example.com而没有任何指定登录凭据,以清除chrome的内存. (6认同)
  • 这对我有用:)我正在使用Chrome版本32.0.1700.102 (5认同)
  • 嗨,我无法在Chrome上使用它进行https. (4认同)
  • 适用于ff和chrome.请注意,在Chrome中,您必须使用用户正在浏览的精确网址.如果您更改URL(甚至更改为受保护的Web文件夹中的其他URL),它将只记住良好的凭据. (3认同)
  • 我认为这个答案绝对需要一些解释!*为什么*以及*如何*凭证被*覆盖*? (2认同)

bob*_*nce 164

基本身份验证不是为了管理注销而设计的.你可以这样做,但不是完全自动的.

您需要做的是让用户单击一个注销链接,并使用相同的域发送'401 Unauthorized'作为响应,并且与您发送请求登录的普通401相同的URL文件夹级别.

必须指示他们接下来输入错误的凭证,例如.一个空白的用户名和密码,作为回应,您发回"您已成功注销"页面.然后,错误/空白凭据将覆盖先前正确的凭据.

简而言之,logout脚本会反转登录脚本的逻辑,只有在用户没有传递正确的凭据时才返回成功页面.

问题是,有点好奇的"不输入密码"密码框是否会满足用户的接受程度.尝试自动填写密码的密码管理员也可能会妨碍这里.

编辑以添加以回应评论:重新登录是一个稍微不同的问题(除非您需要两步注销/登录显然).您必须拒绝(401)第一次尝试访问relogin链接,而不是接受第二次尝试(可能有不同的用户名/密码).有几种方法可以做到这一点.一种方法是在注销链接中包含当前用户名(例如/ relogin?username),并在凭据与用户名匹配时拒绝.

  • W3C在HTML规范上非常活跃.但HTTP规范正在萎缩.大约二十年前,W3C应该已经解决了这个问题.随着REST服务使用的增加,当今需要一种强大的本机身份验证方法. (13认同)
  • 在浏览localhost的Chrome浏览器46中,这似乎无法正常工作.Chrome似乎同时保留旧的(正确的)密码和您指定的新密码.导航到注销页面后,chrome正确使用新密码,直到您在网站页面上未经授权的情况下使用401.在第一个401之后,Chrome会恢复为旧的(正确的)密码.所以它看起来确实没有删除密码. (9认同)
  • 我会尝试这种方法.注销(在这种情况下)是使用户能够以不同的用户身份登录,因此这是完全可以接受的解决方案.对于自动填写密码,如果他将使用它,则取决于用户.谢谢 (2认同)

ddo*_*nko 64

你可以完全用JavaScript完成它:

IE(很长一段时间)用于清除基本身份验证缓存的标准API:

document.execCommand("ClearAuthenticationCache")
Run Code Online (Sandbox Code Playgroud)

当它工作时应该返回true.返回false,undefined或在其他浏览器上爆炸.

新版浏览器(截至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@')
Run Code Online (Sandbox Code Playgroud)

执行上述操作的"异步"方式是使用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*/)
Run Code Online (Sandbox Code Playgroud)

你也可以把它作为书签:

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

  • 我今天使用上面的书签,我运作良好. (2认同)
  • 小书签也可在Edge上使用。只需与`<ahref='javascript:......需要*/);'>注销</a>一起使用 (2认同)

小智 18

以下功能已确认适用于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);
}
Run Code Online (Sandbox Code Playgroud)


Rom*_*net 11

这是一个使用jQuery的非常简单的Javascript示例:

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

    jQuery.get(out).error(function() {
        window.location = to_url;
    });
}
Run Code Online (Sandbox Code Playgroud)

此日志用户没有再次向他显示浏览器登录框,然后将其重定向到已注销的页面

  • window.location= window.location.href.replace(/:\/\//, '://log:out@'); (2认同)

Aln*_*tak 10

基本身份验证无法直接实现这一点.

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

有"hacks"(参见其他答案)通常涉及使用XMLHttpRequest发送带有错误凭据的HTTP请求来覆盖最初提供的HTTP请求.

  • 理论上.从其他答案中可以看出,实践证明了其他方面. (12认同)
  • 正如您还可以从其他答案中看到的那样,不是以可靠,一致和故障安全的方式! (2认同)

Nah*_*eco 9

仅供记录,有一个名为 的新 HTTP 响应标头Clear-Site-Data。如果您的服务器回复包含Clear-Site-Data: "cookies"标头,则应删除身份验证凭据(不仅仅是 cookie)。我在 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.
Run Code Online (Sandbox Code Playgroud)

并且身份验证凭据不会被删除,因此这(目前)无法实现基本的身份验证注销,但也许将来会。没有在其他浏览器上测试。

参考:

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


Chi*_*edo 6

它实际上非常简单.

只需在浏览器中访问以下内容并使用错误的凭据: http:// username:password@yourdomain.com

这应该"让你退出".

  • 重复的答案(见上面的马修韦尔伯恩)。 (2认同)

Teo*_*kis 6

我刚刚在 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>
Run Code Online (Sandbox Code Playgroud)


小智 5

这适用于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"); 
      });
  });          
Run Code Online (Sandbox Code Playgroud)


Env*_*vek 5

您所需要的只是将用户重定向到某个注销 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;
}
Run Code Online (Sandbox Code Playgroud)

错误页面/home/user/errors/401.html

<!DOCTYPE html>
<p>You're not authorised. <a href="<!--# echo var="scheme" -->://<!--# echo var="host" -->/">Login</a>.</p>
Run Code Online (Sandbox Code Playgroud)