PHP:如何检测会话是否已自动过期?

zii*_*web 13 php session

定义会话到期时间时,是否可以在事件监听器到期时调用它?

如果不可能,是否可以运行cron作业来检查会话是否已过期?

注意:我对服务器解决方案感兴趣.我说的是定义了会话到期时间的情况,会话自动结束,因为该时间段已过期.

sym*_*ean 10

可以在事件监听器到期时调用它吗?

简短的回答是否定的

人们往往会忽略一些关于会话的奇怪之处.使用默认处理程序时,会话在gc_maxlifetime结束时不会过期- 这只是数据符合自动删除条件的时间.会话所有者没有动作会触发随后的会话删除 - 这是其他人会话的副作用.

session_write_close()被调用时(由代码结束显式或隐式),如果随机数生成器,通过相关的gc设置调整抛出正确的数字,那么PHP将寻找超过其TTL的数据并将其删除.如果您想在此时触发操作,则需要中断默认处理程序并应用自己的操作.这意味着您不仅需要提供一种识别和删除会话的机制,还需要一种方法来决定您的处理程序是否应该启动以及它应该删除多少个会话 - 您不希望失控的进程杀死您的服务器.

在Ubuntu中,session.gc_probability = 0它是一个执行删除陈旧数据文件功能的cron作业.

您的问题中遗漏的一条非常重要的信息是删除会话的原因.

如果要防止敏感数据在文件系统上持久存在,那么更好的解决方案是使用另一个客户端cookie中存储的密钥(仅)来加密数据.这样您就可以完全消除服务器上未受保护数据的存储.(请注意,suhosin的加密会话使用从客户端数据派生的密钥和存储在同一主机上的静态密钥 - 这比随机生成的密钥安全性低得多).这是我之前准备的.

如果您只想在gc_maxlifetime过期后阻止访问,则应考虑将自定义会话处理程序视为缺失的自定义会话处理程序.即它在到期时并未真正注销,但任何后续请求都不能再与会话相关联.Stackable会话处理程序示例中的安全层实现了这样的控制.

OTOH如果你想在你的事件监听器中使用会话中的数据,那么这是一个不同的故事 - 你肯定无法使用Suhosin或我的加密数据.但更复杂的是,数据的(默认)格式与其他地方使用的格式不同.您需要使用session_encode()和session_decode().前者只会从$ _SESSION数组中读取数据,因此对会话的窃听需要对session_id()and进行一些小心的颠覆session_start().session_decode()但是会愉快地转换你投掷的任何东西.

在最新版本的PHP中,您可以指定用于序列化/反序列化的不同函数对.

在考虑将要读取会话文件中的数据的会话垃圾收集器时,考虑方法的潜在影响是至关重要的__wakeup().与此相关的是要求处理此类垃圾收集的进程在与创建会话数据的原始PHP进程相同的uid下运行(否则您具有权限提升后门).但是,如果会话存储基板是基于文件的,那么无论如何都需要这样.

会话数据解串器的实现是用PHP以外的语言编写的,它们可以提供针对__wakeup()攻击的保护(尝试谷歌),虽然这可能是解决问题的过度杀伤,但它们可能没有被积极维护.如果这是一个问题,那么更合适的解决方案可能是使用WDDX(xml)序列化程序并使用传统的XML解析器来读取GC引擎中的数据.

如果您使用本机处理程序正常读取和写入数据但想要实现自己的垃圾收集器,那么您将需要代码将映射session_id到文件路径.如果你按照我给上面的PHP类的链接,你会看到几个会话处理程序的纯PHP实现,包括与本机处理程序兼容的那些.

但是我强烈建议你在选择在删除时回读会话数据之前用尽所有其他途径来解决任何潜在的问题.


小智 5

你也可以用这个:)

<? 
session_start();

$time = 3600; // Set expire time with secends.
// Star session here 
if (isset($_SESSION['time']) && (time() - $_SESSION['time']) > $time) {
   // Your Code Here to logout
   header('location: /auth/logout');
   exit();
} else {
  $_SESSION['time'] = time();
 }
Run Code Online (Sandbox Code Playgroud)


小智 -1

我们可以使用您定义的会话变量。

if(isset($_SESSION['variable'])){
    //do something
}
Run Code Online (Sandbox Code Playgroud)

例子:

if(isset($_SESSION['name'])){
    echo "Session has not expired"; 
}
Run Code Online (Sandbox Code Playgroud)

  • 他不想暂停吗? (3认同)