存储HTTP基本身份验证凭据,直到浏览器关闭,但有没有办法在浏览器关闭之前删除凭据?
我读过trick with HTTP 401 status code,但似乎是work not properly(请参阅评论回答)。也许是mechanism trac uses is the solution。
可以使用JavaScript删除凭据吗?或者结合使用JavaScript和状态401技巧?
答案 0 :(得分:33)
更新:此解决方案在许多浏览器中似乎不再起作用。 Kaitsu的评论:
这种发送虚假凭据以使浏览器忘记正确的经过身份验证的凭据的解决方案在Chrome(16)和IE(9)中不起作用。适用于Firefox(9)。
实际上,您可以通过向服务发送虚假凭据来实施解决方法。这可以在浏览器中通过发送另一个(不存在的?)用户名而无需密码。浏览器丢失有关经过身份验证的凭据的信息。
示例:
https://www.example.com/ =>登录 使用基本身份验证作为“user1”
现在打开
https://foobar@www.example.com/
您已退出。 ;)
此致
P.s。:但是,在依赖给定信息之前,请使用所有需要的浏览器进行测试。
答案 1 :(得分:10)
扩大Jan.的答案,并更新owyongsk的答案:
以下是一些示例jquery java-script代码,它使浏览器基本上向您尝试保护的页面发送伪造的登录请求,这在所有测试的浏览器中都会导致缓存的凭据被删除,然后将用户重定向到不受保护的页面。
出现问题时的alert()可能应该更改为其他内容。
//Submits an invalid authentication header, causing the user to be 'logged out'
function logout() {
$.ajax({
type: "GET",
url: "PUT_YOUR_PROTECTED_URL_HERE",
dataType: 'json',
async: true,
username: "some_username_that_doesn't_exist",
password: "any_stupid_password",
data: '{ "comment" }'
})
//In our case, we WANT to get access denied, so a success would be a failure.
.done(function(){
alert('Error!')
})
//Likewise, a failure *usually* means we succeeded.
//set window.location to redirect the user to wherever you want them to go
.fail(function(){
window.location = "/";
});
}
然后就像注销链接调用logout()函数一样简单,它似乎可以无缝地为用户工作,尽管它在技术上仍然是一个黑客工作。
答案 2 :(得分:7)
您可以尝试使用最新的Chrome和Firefox进行黑客攻击。在服务器上创建一个“/ logout”页面,该页面只接受某个凭据,例如username:false,password:false。然后使用下面的AJAX请求,您可以将用户发送到该页面。
$("#logout").click(function(e){
e.preventDefault();
var request = new XMLHttpRequest();
request.open("get", "/logout", false, "false", "false");
request.send();
window.location.replace("WHEREVER YOU WANT YOUR LOGGED OUT USER TO GO");
});
错误的用户名和密码是从有效的XMLHttpRequest而不是当前用户的凭据缓存的,当用户尝试登录任何页面时,它将使用缓存的虚假凭据,无法进行身份验证,它将要求用户输入另一个。希望这有帮助!
答案 3 :(得分:4)
刚刚完成一个对我有用的实现: 在服务器上我评估会话,用户名和密码,所以我跟踪这些信息,登录算法如下:
1.检查用户和密码是否为空,否则返回401。
2.检查我们是否已在登录用户列表中注册会话,如果没有,则检查用户和密码是否有效,如果是,请在列表中保存会话ID,然后返回401。 我将解释这一步:如果会话ID不同,则发生以下三种情况之一: a)用户正在打开另一个窗口。 b)用户会话已完成,即用户已注销。 c)会议由于不活动而到期。 但是我们想要保存会话,只要用户凭据有效但返回401一次要求输入密码,如果我们不保存会话那么用户就永远无法登录,因为我们没有新的会话ID在我们的列表中。
3.检查用户凭据是否正确,如果是,保存会话信息并继续提供服务页面,否则返回401.
因此,我必须注销用户的唯一方法是在用户请求注销页面时关闭服务器上的会话,并且Web浏览器再次显示登录对话框。
我在想这个时候必须有一个步骤,程序检查用户是否已经登录以避免冒充,也许我可以为每个用户保存多个会话ID以允许多个会话,嗯,我想对你提出意见。
希望你能得到这个想法,如果你发现任何安全漏洞,请发表评论;)
答案 4 :(得分:4)
您可以使用JavaScript删除凭据:
$("#logout").click(function(){
try {
document.execCommand("ClearAuthenticationCache");
window.location.href('/logout.html'); // page with logout message somewhere in not protected directory
} catch (exception) {}
});
此代码仅适用于IE。这就是为什么在那里添加try / catch块的原因。 此外,出于同样的原因,您应该仅为IE用户显示注销链接:
<!--[if IE]>
<div id="logout">[Logout]</div>
<![endif]-->
对于其他用户,我的建议如下:
<div id="logout2" onclick="alert('Please close your browser window to logout')">[Logout]</div>
答案 5 :(得分:3)
如果您可以控制服务器代码,则可以创建&#34;注销&#34;回复&#34; 401 Unauthorized&#34;无论给出的凭据如何。此故障会强制浏览器删除已保存的凭据。
我刚刚使用Chrome 34,IE 11,Firefox 25进行了测试 - 使用Express.js服务器和HTTP基本身份验证。
答案 6 :(得分:0)
在Chrome(版本66)中对我有用的是向返回401的URL发送Ajax请求。这样就可以清除基本身份验证缓存。
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "/url_that_returns_401", true);
xhttp.send();
答案 7 :(得分:0)
以下代码在Chrome(版本83)中对我有效:
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "/url_that_return_401", true);
xhttp.setRequestHeader('Authorization', 'Basic ');
xhttp.send();
需要执行此代码(可能通过单击按钮或控制台窗口),然后出现提示,您需要按“取消”按钮。然后,身份验证字段将清除,您可以刷新页面并使用其他凭据登录。
答案 8 :(得分:0)
将随机数标记为无效。我对服务器端进行了 Ajax 调用,要求注销。服务器端在标头中获取“身份验证:摘要...”请求。它从该行中提取 nonce="" 并将其添加到禁用的 nonce 列表中。因此,下次浏览器发送带有“身份验证:摘要...”行的请求时,服务器回复 401。这使浏览器要求用户输入新的用户 ID/密码。
适用于我的应用程序,但仅适用于摘要式身份验证。