如何在 30 分钟后使 PHP 会话过期? [英] How do I expire a PHP session after 30 minutes?

查看:23
本文介绍了如何在 30 分钟后使 PHP 会话过期?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to keep a session alive for 30 minutes and then destroy it.

推荐答案

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

You should implement a session timeout of your own. Both options mentioned by others (session.gc_maxlifetime and session.cookie_lifetime) are not reliable. I'll explain the reasons for that.

首先:

session.gc_maxlifetime
session.gc_maxlifetime 指定数据将被视为垃圾"并被清理的秒数.垃圾收集发生在会话开始期间.

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%.

But the garbage collector is only started with a probability of session.gc_probability divided by session.gc_divisor. And using the default values for those options (1 and 100 respectively), the chance is only at 1%.

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

Well, you could simply adjust these values so that the garbage collector is started more often. But when the garbage collector is started, it will check the validity for every registered session. And that is cost-intensive.

此外,当使用 PHP 的默认 session.save_handler 文件,会话数据存储在 session.save_path.使用该会话处理程序,会话数据的年龄是根据文件的最后修改日期而不是最后访问日期计算的:

Furthermore, when using PHP's default session.save_handler files, the session data is stored in files in a path specified in session.save_path. With that session handler, the age of the session data is calculated on the file's last modification date and not the last access date:

注意:如果您使用默认的基于文件的会话处理程序,您的文件系统必须跟踪访问时间 (atime).Windows FAT 没有,因此如果您被 FAT 文件系统或任何其他时间跟踪不可用的文件系统卡住,您将不得不想出另一种方法来处理垃圾收集您的会话.从 PHP 4.2.3 开始,它使用了 mtime(修改日期)而不是 atime.因此,您不会遇到 atime 跟踪不可用的文件系统问题.

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.

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

So it additionally might occur that a session data file is deleted while the session itself is still considered as valid because the session data was not updated recently.

第二:

session.cookie_lifetime
session.cookie_lifetime 指定发送到浏览器的 cookie 的生命周期(以秒为单位).[…]

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 仅在浏览器关闭前有效.

Yes, that's right. This only affects the cookie lifetime and the session itself may still be valid. But it's the server's task to invalidate a session, not the client. So this doesn't help anything. In fact, having session.cookie_lifetime set to 0 would make the session’s cookie a real session cookie that is only valid until the browser is closed.

结论/最佳解决方案:

最好的解决方案是实现您自己的会话超时.使用一个简单的时间戳来表示最后一个活动(即请求)的时间,并随着每个请求更新它:

The best solution is to implement a session timeout of your own. Use a simple time stamp that denotes the time of the last activity (i.e. request) and update it with every request:

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

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

Updating the session data with every request also changes the session file's modification date so that the session is not removed by the garbage collector prematurely.

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

You can also use an additional time stamp to regenerate the session ID periodically to avoid attacks on sessions like session fixation:

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 应该至少等于这个自定义过期处理程序的生命周期(在这个例子中是 1800);
  • 如果您想在 activity 30 分钟后而不是 开始后 30 分钟后使会话过期,您还需要使用 setcookiecode> 的过期时间为 time()+60*30 以保持会话 cookie 处于活动状态.
  • 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.

这篇关于如何在 30 分钟后使 PHP 会话过期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆