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

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

问题描述

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

解决方案

您应该实现自己的会话超时。其他人提及的两个选项( session.gc_maxlifetime session.cookie_lifetime )不可靠。


session.gc_maxlifetime

session.gc_maxlifetime 指定数据将被视为垃圾并清理的秒数。


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



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



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


注意:如果您使用默认的基于文件的会话处理程序,则文件系统必须跟踪访问时间(atime)。 Windows FAT不是这样,你将不得不提出另一种方式来处理垃圾收集会话,如果你被困在FAT文件系统或任何其他文件系统,其中atime跟踪不可用。从PHP 4.2.3它已经使用mtime(修改日期)而不是atime。因此,您不会遇到无法使用atime跟踪的文件系统的问题。


因此,可能会出现会话数据文件



其次:


session.cookie_lifetime

session.cookie_lifetime 指定Cookie的有效期以秒为单位发送到浏览器。 [...]


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



/ best solution:



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

  if isset($ _ SESSION ['LAST_ACTIVITY'])&&(time() -  $ _SESSION ['LAST_ACTIVITY']> 1800)){
//上次请求已超过30分钟
session_unset(); // unset $ _SESSION变量的运行时
session_destroy(); // destroy session data in storage
}
$ _SESSION ['LAST_ACTIVITY'] = time(); //更新最后活动时间戳

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



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

  if(!isset($ _ SESSION ['CREATED'])){
$ _SESSION ['CREATED'] = time();
} else if(time() - $ _SESSION ['CREATED']> 1800){
// session starts than 30分钟前
session_regenerate_id // change session ID for the current session and invalidate old session ID
$ _SESSION ['CREATED'] = time(); // update creation time
}

注意: p>


  • session.gc_maxlifetime 应至少等于此自定义到期处理程序的生命周期1800);
  • 如果您想要在 30分钟后而不是在开始后30分钟后使会话过期,
    < ,您还需要使用 time()+ 60 * 30 到期的 setcookie Cookie活动。

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

解决方案

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.

First:

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.

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.

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:

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.

And second:

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

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.

Conclusion / best solution:

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.

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
}

Notes:

  • 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天全站免登陆