如果你想要严格的保证,会话超时是一个必须在代码中实现的概念;这是唯一的方法,您可以绝对确定在 X 分钟不活动后不会有任何会话存活。
如果稍微放宽这一要求是可以接受的,并且您可以设置下限而不是对持续时间进行严格限制,那么您可以轻松地做到这一点,而无需编写自定义逻辑。
轻松环境中的便利性:如何以及为什么
如果您的会话是使用 cookie 实现的(它们可能是),并且如果客户端不是恶意的,您可以通过以下方式设置会话持续时间的上限调整某些参数。如果您使用 PHP 的默认会话处理和 cookie,设置 session.gc_maxlifetime 和 session_set_cookie_params 应该适合您:
// server should keep session data for AT LEAST 1 hour
ini_set('session.gc_maxlifetime', 3600);
// each client should remember their session id for EXACTLY 1 hour
session_set_cookie_params(3600);
session_start(); // ready to go!
这通过配置服务器以保持会话数据至少一小时不活动并指示您的客户端他们应该在相同的时间跨度后“忘记”他们的会话 ID 来工作。 这两个步骤都是实现预期结果所必需的。
-
如果您不告诉客户在一小时后忘记他们的会话 ID(或者如果客户是恶意的并选择忽略您的指示),他们将继续使用相同的会话 ID,其有效持续时间将是不确定的.这是因为在服务器端过期的会话不会立即被垃圾收集,而只会被whenever the session GC kicks in。
GC 是一个潜在的昂贵过程,因此概率通常很小甚至为零(获得大量点击的网站可能会完全放弃概率 GC,并安排它每 X 分钟在后台发生一次)。在这两种情况下(假设非合作客户端),有效会话生命周期的下限都是session.gc_maxlifetime,但上限是不可预测的。
-
如果您没有将session.gc_maxlifetime 设置为相同的时间跨度,那么服务器可能会更早地丢弃空闲会话数据;在这种情况下,仍然记得其会话 ID 的客户端将显示它,但服务器将找不到与该会话关联的数据,实际上就像会话刚刚开始一样。
关键环境中的确定性
您可以通过使用自定义逻辑来使事情完全可控,同时在会话不活动上放置一个上限;加上上面的下限,这导致了严格的设置。
通过将上限与会话数据的其余部分一起保存来做到这一点:
session_start(); // ready to go!
$now = time();
if (isset($_SESSION['discard_after']) && $now > $_SESSION['discard_after']) {
// this session has worn out its welcome; kill it and start a brand new one
session_unset();
session_destroy();
session_start();
}
// either new or old, it should live at most for another hour
$_SESSION['discard_after'] = $now + 3600;
会话 id 持久性
到目前为止,我们根本不关心每个会话 id 的确切值,只关心数据只要我们需要就应该存在的要求。请注意,在(不太可能)会话 ID 对您很重要的情况下,必须小心在需要时使用 session_regenerate_id 重新生成它们。