如果用户使用基本身份验证,是否可以从网站注销用户?
杀戮会话是不够的,因为一旦用户通过身份验证,每个请求都包含登录信息,因此用户下次使用相同的凭据访问站点时会自动登录.
到目前为止,唯一的解决方案是关闭浏览器,但从可用性的角度来看,这是不可接受的.
除了答案之外...
使用Ajax,您可以将"Logout"链接/按钮连接到Javascript函数.让此函数使用错误的用户名和密码发送XMLHttpRequest.这应该返回401.然后将document.location设置回登录前页面.这样,用户在注销时将永远不会看到额外的登录对话框,也不必记得输入错误的凭据.
让用户点击https:// log:out@example.com/的链接.这将用无效的凭证覆盖现有的凭证; 记录它们.
基本身份验证不是为了管理注销而设计的.你可以这样做,但不是完全自动的.
您需要做的是让用户单击一个注销链接,并使用相同的域发送'401 Unauthorized'作为响应,并且与您发送请求登录的普通401相同的URL文件夹级别.
必须指示他们接下来输入错误的凭证,例如.一个空白的用户名和密码,作为回应,您发回"您已成功注销"页面.然后,错误/空白凭据将覆盖先前正确的凭据.
简而言之,logout脚本会反转登录脚本的逻辑,只有在用户没有传递正确的凭据时才返回成功页面.
问题是,有点好奇的"不输入密码"密码框是否会满足用户的接受程度.尝试自动填写密码的密码管理员也可能会妨碍这里.
编辑以添加以回应评论:重新登录是一个稍微不同的问题(除非您需要两步注销/登录显然).您必须拒绝(401)第一次尝试访问relogin链接,而不是接受第二次尝试(可能有不同的用户名/密码).有几种方法可以做到这一点.一种方法是在注销链接中包含当前用户名(例如/ relogin?username),并在凭据与用户名匹配时拒绝.
你可以完全用JavaScript完成它:
IE(很长一段时间)用于清除基本身份验证缓存的标准API:
document.execCommand("ClearAuthenticationCache")
当它工作时应该返回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@')
执行上述操作的"异步"方式是使用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="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*/);
以下功能已确认适用于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);
}
这是一个使用jQuery的非常简单的Javascript示例:
function logout(to_url) { var out = window.location.href.replace(/:\/\//, '://log:out@'); jQuery.get(out).error(function() { window.location = to_url; }); }
此日志用户没有再次向他显示浏览器登录框,然后将其重定向到已注销的页面
基本身份验证无法直接实现这一点.
HTTP规范中没有机制告诉浏览器停止发送用户已经提供的凭据.
有"hacks"(参见其他答案)通常涉及使用XMLHttpRequest发送带有错误凭据的HTTP请求来覆盖最初提供的HTTP请求.
它实际上非常简单.
只需在浏览器中访问以下内容并使用错误的凭据: 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"); }); });