问题:常识会告诉我,与会话进行积极交互的任何内容都将构成会话活动,并将重置确定会话超时和销毁的不活动计时器。那不是我的经验。我正在尝试确定我是否对会话的工作方式有基本的误解,或者我的代码中有一个深奥的错误,导致我对PHP会话的基础提出质疑。
上下文:我正在为Web应用程序的用户实现永久性登录。我一直在试图找出导致会话闲置/超时的原因,但几天没有成功。我已经遍历了stackoverflow和整个Internet(包括有关会话的大多数PHP文档),但我仍然觉得自己一直在坚持不懈。
据我所知,“记住我” Cookie与数据库条目进行交叉引用以进行用户查找,是使用户在不活动和关闭登录状态期间保持登录状态的首选方法-在浏览器实例中。我接受这一点,并且我相信我知道该怎么做(在线上有很多关于这种方法的很好的信息),但是,我最初试图简化所需的适度工作通过简单地调整一些会话配置参数,即cookie_lifetime
和gc_maxlifetime
,可以实现这种方法。我希望增加这些参数会增加会话超时所花费的时间,但事实并非如此。我将两个参数都设置为1年,并且会话在大约40分钟后仍然超时(这也很奇怪;我在网上发现的所有内容都表明24分钟是默认超时)。接下来,我试图完全避开不活动状态,并添加了一个“心跳” ajax请求,该请求每10分钟对服务器执行一次ping操作,重新生成会话ID并任意修改会话密钥/值存储。该实验产生了相同的40分钟超时结果,而ajax调用在第4次调用中始终失败。
以下是一些[简化的]代码,以防我在错误的地方寻找问题的来源:
/* initialize_session.php (called at the beginning of every php file) */
$heartbeat_timer = 60 * 10; // 10 minutes.
if(session_id() == '' || !isset($_SESSION)){
# Some of these are already the defaults, but I'm being explicit to avoid ambiguity.
$session_params = array(
# Ensure that session file persists beyond heartbeat for keeping alive.
"gc_maxlifetime" => $heartbeat_timer + 60,
"cookie_lifetime" => 0,
"cookie_path" => "/",
"cookie_domain" => "shhhh.com",
"use_strict_mode" => TRUE,
"cookie_secure" => TRUE,
"cookie_httponly" => TRUE,
"use_cookies" => TRUE,
"use_only_cookies" => TRUE,
);
session_start($session_params);
}
/* any_page.php (html page where "inactivity" & timeout occur) */
<?php require_once __DIR__ . "/initialize_session.php"; ?>
<body>
blah blah blah
<script>
setInterval(function(){
$.ajax({
"url": "keep_alive.php",
"type": "POST",
"error": function(xhr, text_status, error_thrown){
// Log error stuff (incidentally, not helpful).
}
});
}, 600000/* 10 minutes in msec */);
</script>
</body>
/* keep_alive.php (arbitrary session modification to trick app into thinking I'm active) */
require_once __DIR__ . "/initialize_session.php";
session_regenerate_id(TRUE);
$_SESSION["last_heartbeat"] = time();
可能值得注意的是,会话文件的服务器文件存储和会话ID的客户端cookie均每10分钟根据重新生成的会话ID进行正确更新。 Ajax间隔刚开始在第四个请求上失败(如我所说,与所有实验之前的会话不活动超时一致)。
让我知道是否可以提供更多信息来帮助解决问题。再次感谢!
答案 0 :(得分:0)
从每个人对我的问题的评论中所做的贡献来看,我可以肯定的是我的应用程序中存在一个错误,并且它对我理解会话基本原理起到了很多作用。我对会话不活动和超时的假设似乎是正确的。到达问题根源后,我将编辑问题和答案。
答案 1 :(得分:0)
允许我提出另一种考虑方法。
我不会依赖PHP设置来获得一致的结果,因为即使了解所有这些选项如何协同工作也是一项艰巨的任务。
我(在服务器端,在您的应用程序中)将最后一个活动时间戳记与会话ID(存储在cookie中的那个)一起存储。然后,您可以使用它来了解您是否仍要保持用户登录状态。然后,您可以根据需要在heartbeat
中更新此条目。
然后,您可以将PHP配置设置为会话超时。
这将使调试变得更容易,并且以后-如果您想实施警告警报(“您将在10、9、8 ...中登出”)也将变得更加容易。