问题

我需要保持一个会话活30分钟,然后销毁它.



解决方法

您应该实现自己的会话超时.其他人提及的两个选项( session.gc_maxlifetime < / em> 会话. cookie_lifetime )不可靠.我会解释原因.

第一:

session.gc_maxlifetime
session.gc_maxlifetime specifies the number of seconds after which data will be seen as 'garbage' and cleaned up. Garbage collection occurs during session start.

但是垃圾回收器只能以 session.gc_probability 除以 session.gc_divisor .并使用这些选项的默认值(分别为1和100),机会只有1%.

好吧,你可以简单地调整这些值,以便垃圾收集器更频繁地启动.但是当垃圾收集器启动时,它将检查每个注册会话的有效性.这是成本密集型.

此外,在使用PHP的默认 会话时.save_handler 文件中,会话数据存储在 session.save_path .使用该会话处理程序,会话数据的寿命将根据文件的上次修改日期而不是上次访问日期计算:

Note: If you are using the default file-based session handler, your filesystem must keep track of access times (atime). Windows FAT does not so you will have to come up with another way to handle garbage collecting your session if you are stuck with a FAT filesystem or any other filesystem where atime tracking is not available. Since PHP 4.2.3 it has used mtime (modified date) instead of atime. So, you won't have problems with filesystems where atime tracking is not available.

因此,可能会发生会话数据文件被删除,而会话本身仍被视为有效,因为会话数据最近未更新.

第二个:

session.cookie_lifetime
session.cookie_lifetime specifies the lifetime of the cookie in seconds which is sent to the browser. […]

是的,没错.这只会影响Cookie生命周期,会话本身仍然有效.但是服务器的任务是使会话无效,而不是客户端.所以这不帮助什么.实际上,将 session.cookie_lifetime 设置为 0 会使会话的Cookie成为一个真实的会话Cookie ,只有在浏览器关闭后才有效.

结论/最佳解决方案:

最佳解决方案是实现您自己的会话超时.使用简单的时间戳记表示上次活动(即请求)的时间,并使用每个请求更新:

if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) {
    // last request was more than 30 minutes ago
    session_unset();     // unset $_SESSION variable for the run-time 
    session_destroy();   // destroy session data in storage
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp

每次请求更新会话数据也会更改会话文件的修改日期,以便会话不会被垃圾回收器过早删除.

您还可以使用附加的时间戳记定期重新生成会话ID,以避免对会话的攻击,例如会话固定:

if (!isset($_SESSION['CREATED'])) {
    $_SESSION['CREATED'] = time();
} else if (time() - $_SESSION['CREATED'] > 1800) {
    // session started more than 30 minutes ago
    session_regenerate_id(true);    // change session ID for the current session and invalidate old session ID
    $_SESSION['CREATED'] = time();  // update creation time
}

注意:

  • session.gc_maxlifetime should be at least equal to the lifetime of this custom expiration handler (1800 in this example);
  • if you want to expire the session after 30 minutes of activity instead of after 30 minutes since start, you'll also need to use setcookie with an expire of time()+60*30 to keep the session cookie active.



相关问题推荐