【问题标题】:PHP SESSION destroy when user close the browser or automatic session destroy当用户关闭浏览器或自动会话销毁时 PHP SESSION 销毁
【发布时间】:2015-01-12 20:11:23
【问题描述】:


我的登录-注销脚本中有一个漏洞,我真的不知道如何填补它。 当用户开始简单地离开页面而不是注销时,整个问题就出现了。实际上不会有什么不好的,因为在我的代码中有 15 分钟后注销(会话超时),但在我的数据库中有一个“在线”列在登录和注销时更改,所以当用户只是关闭它不会更改为脱机的页面。

我正在尝试将 window.onbeforeunload 链接到注销所在的页面(没有用) 我也听说过 cron,但我完全不知道如何做到这一点。

谁能告诉我如何通过详细解释解决我的问题?
期待您的回音。

【问题讨论】:

  • 不可能。您无法可靠地检测到一个人何时关闭窗口或选项卡......您将如何检测用户是否在您的网站上打开了多个选项卡并关闭了一个?现在他们已在所有选项卡中注销。无论如何,PHP 本身都会清理过时的会话。除了设置会话生命周期之外,您不需要做任何事情 - 让 PHP 来处理它。
  • 我想查看在线的人并且我的数据库中有它,我应该怎么做呢?
  • 将“谁现在在线”更改为“谁在过去 15 分钟内做了什么”。
  • 同意 Marc B 的观点。您可能会分析用户的最后活动日期,然后轮询该信息。如果人们在过去五分钟左右没有做任何事情,请添加“空闲”状态或其他内容。如果他们在会话过期所需的时间内没有做任何事情,则更新 UI 以离线显示。
  • 一切都保存在数据库中,所以也许我会在 db 中设置类似预期的注销时间并每 15 分钟运行一次此脚本? (使用 cron)

标签: php session cron onbeforeunload


【解决方案1】:

一个解决方案可能是每次页面加载或每个页面的 ajax 请求将代码反弹到服务器以说“嘿,此用户在线”,然后在您的脚本中添加一个内置函数 (可以在任何页面上工作,任何人都可以查看)以检查 mysql 更新时间是否在最后 X 分钟内,如果不是,则假定用户已注销。

我想我已经解释得很糟糕了。

您的表中有一个时间戳字段 - 与每个登录的用户相关联,如果上次更新的时间戳在现在的 X 分钟内,则他们被视为在线,

因此,每次加载页面或每次处理 ajax 调用时,都会更新 timstamp 字段,然后在时间戳早于 X 分钟的任何字段上,这是因为他们(可能)已注销因此它们在数据库中被更改为“离线”。虽然如果他们只是忙并且仍然在线,也许实际上不要将他们注销,只需将他们标记为离线。

我没有详细说明您如何处理数据库内容详细信息等,所以我的想法可能与您可以创建的内容完全不同 - ?

编辑: Ajax 建议

要让 ajax 每 X 秒作用于每个页面,请将以下 ajax 写入成员所在的页面,注意末尾的数字是毫秒,600000 = 10 分钟。所以使用了 500000,因为它在时间范围内。所以 ajax 函数每 8.5 分钟运行一次,或者在页面加载时运行。

ajax 写得很糟糕,可能还可以改进。但应该工作。您需要研究更优化的 ajax 脚本。

浏览器页面:

<script src="js/jquery-1.11.1.min.js" type="text/javascript" ></script>
 <script type="text/javascript">

     $( document ).ready(function() {
    var memberId = <?php print $memberId; ?>;
var securityKey = <?php print some security key code or suchlike to validate this ajax at the otherend;?>;

         setInterval(function(){
         $.post("/ajaxSession.php",{
                MemberId: memberId,
                somesecuritykey: securityKey
            });
        }, 500000);
    });

</script> 

AJAX 页面: 请注意,在这种情况下,更新时间是一个“时间戳”MySQL 字段。

    <?php
    /**
    Setup this page as if any other PHP page but this page will never show to the browser,
    AJAX data is supplied as $_POST and inn this case $_POST['somesecuritykey'] and $_POST['MemberId'] 
    **/

session_start();
/**
include classes and files
**/
if (is_numeric($_POST['MemberId'])){
$memid= (int)$_POST['MemberId'];

/**Also include your security stuff here **/

$sql = "UPDATE Members SET UpdateTime = NOW() , LoggedIn = 'YES' WHERE MemberId = ? LIMIT 1"
$mysqli = new mysqli();
$mysqli->prepare($sql);
$mysqli->bind_param("i",$memid);
$mysqli->execute();

}

这应该保持时间戳值是最新的,所以登录的人是更新时间大于 time()-601(10:01 分钟)的任何人,SQL 列表可以在任何人发生的任何标题/类上更改它访问任何页面

SQL = "UPDATE Members SET LoggedIn = 'NO' WHERE UpdateTime < (NOW() - INTERVAL 10 MINUTE)"

【讨论】:

  • 好吧,我想我有个主意。我将每 15 分钟运行一次脚本以检查用户上次活动是否在 15 分钟内。我正在使用 php 和 mysql。
  • 所以有一个名为 LoginTimestamp 或其他名称的列,然后每 10 分钟左右运行一次 ajax,将其保持在 15 分钟的最长时间内,查看它们是否在线,然后更新时间戳,并且您在任何构造函数中都内置了代码,以在用户的​​时间戳
  • 唯一的问题是每个用户每 1 分钟进行一次这种更新会增加服务器流量,所以如果您只有少量用户和/或大量的免费服务器资源,每 5 或 3 或 2 分钟有一个更常见的 ajax 等,这不是问题。
  • 但是有个问题——我不懂ajax,能不能给我写代码或者写步骤怎么办?脚本在 x 分钟后运行,什么?我如何使用ajax与mysql通信?当用户关闭页面时它会起作用吗?
  • 我会给你写一个 ajax 建议作为对这个答案的修改。
猜你喜欢
  • 1970-01-01
  • 2014-08-15
  • 1970-01-01
  • 1970-01-01
  • 2012-07-29
  • 2015-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多