我有一个PHP应用程序,它在登录MYSQL表时存储了用户的会话ID,当用户注销并通过注销过程销毁它们的会话时,该表被删除。如果MYSQL表在该session_id列中仍有值,则不允许用户再次登录。这在自然触发的注销的情况下非常有用。但是,当用户只是关闭浏览器窗口/选项卡时,似乎服务器保留了会话变量,而且由于未调用自然的logout.php,MySQL表中的session_id列也没有被清空。因此,我可以在同一台计算机上输入受登录保护的任何URL,然后直接进入。这是一个安全问题 - 由不遵循自然退出指令的用户触发而不仅仅是关闭浏览器窗口。
我已经关注SO thread here并试图使用onbeforeunload()JS函数来处理浏览器关闭的这种情况。如您所知,当发生这4个事件中的任何一个时,onbeforeunload()事件被触发 - (1)浏览器关闭(2)通过单击""从页面导航到另一个页面。链接(3)刷新页面(4)提交表格。
在下面的代码中,我在(1)和(3)中遇到以下问题,我很难搞清楚: 问题1.当我关闭浏览器窗口时,我会通过" Stay On the Page"和"离开Page"选项。但是,对于 call_my_special_script.php 的AJAX调用正在两个选项上发生,而在"留在页面上时不应该发生这种情况。 call_my_special_script.php 只是删除MySQL表中session_id的内容。 问题2.当我刷新浏览器时 - Safari / IE代码说什么都不应该发生,但是当我不期待它时,我会看到警报。无论我在警报上选择了什么,它都会调用 call_my_special_script.php 并删除session_id值。
我应该在这里做些什么来解决这些问题?
<script>
var validNavigation = false;
function browserCloseEvents() {
var dont_confirm_leave = 0;
var leave_message = 'You sure you want to leave the page?'
function goodbye(e) {
if (!validNavigation) {
if (dont_confirm_leave!==1) {
if(!e) e = window.event;
e.cancelBubble = true;
e.returnValue = leave_message;
if (e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
$.ajax({
type: 'GET',
url: "call_my_special_script.php",
async: false,
success: function () {
alert("sucess");
}
});
return leave_message;
}
}
}
window.onbeforeunload = goodbye;
$(document).bind('keypress', function(e) {
if (e.keyCode == 116){
validNavigation = true;
}
});
$("a").bind("click", function() {
validNavigation = true;
});
$("form").bind("submit", function() {
validNavigation = true;
});
$("input[type=submit]").bind("click", function() {
validNavigation = true;
});
}
$(document).ready(function() {
browserCloseEvents();
});
答案 0 :(得分:0)
与往常一样,您应该从不将应用程序的安全性建立在某些客户端功能上。因为它们可以(将)轻松绕过。
在您的情况下,您可以将会话时间设置为 15分钟并且在用户登录时只需发送一个AJAX信标请求以重置该计时器每隔5分钟说 因此,当用户浏览您的网站时,他将登录,如果他意外/有意地关闭了标签,他仍然可以重新打开您的网站并仍然只能在 15分钟内登录的时间跨度。之后他必须重新登录,因为他的会话已经过期。
我见过各种CMS使用这种技术。
你也可以像其他一些AJAX调用一样捎带其他请求来查看新消息..等等。就像 StackOverflow 那样。
答案 1 :(得分:0)
在我看来,在这种情况下你根本不应该依赖JavaScript,原因如下:
无法可靠告知用户是否实际离开了您的网页。
您还必须考虑大量的浏览器和操作系统行为。
示例:
另外,我认为这是非常糟糕的做法:
如果MYSQL表在该session_id列中仍有值,则不允许用户再次登录。
我看到人们试图以“安全理由”来证明这一点,但它确实没有添加任何内容。
如果有攻击者窃取了您的用户名和密码,则会阻止他们在您登录时登录,但这也会阻止您同时他们他们已登录!
(如果有人有你的密码,安全性早就被破坏了。)
如果他们偷了你的会话cookie,它根本不会保护你。
当你登录设备1并希望登录设备2时,它唯一能做的就是惹恼你。
setcookie
功能,当浏览器关闭时, 将被删除。告知用户何时“离开”的最简单方法是,如果您有一个打开的连接,当用户离开时该连接将关闭。
这是不 HTTP(S)的情况 - 它基于后续请求
但是,对于WebSockets, 。
现在,想法是:
对于较旧的浏览器,您可以添加一个AJAX回退,这也可以,但比WebSockets产生更多的流量。
上升空间:
缺点: