PHP会话提前到期

pwa*_*ing 7 php session

我在工作中运行的PHP站点出现问题,几分钟后用户正在注销(确切的时间有所不同,但它经常出现问题),无论他们是否积极使用该站点或不.

困难在于我无法重现这个问题,如果我使用相同的浏览器登录我不会被注销,这表明这不是网站完全被破坏的情况.不幸的是,我无法访问用户计算机来运行任何流量嗅探软件.

我已经检查的东西是:

  • 要求用户尝试不同的浏览器.这似乎并没有解决问题,也不是一个长期的解决方案,因为我无法决定客户将使用哪些浏览器.
  • 服务器时间正确且与用户计算机一致.
  • 用户Apache运行时有权写入会话文件夹,我可以看到正在创建的会话文件及其修改时间正在更新.
  • 没有使用输出缓冲功能.
  • 这个问题发生在各种各样的页面上,似乎没有任何共同之处(也就是说,并不是说它们都使用AJAX,或者更新数据库或其他原因).
  • 用户只能从一台机器上访问他们的帐户,即他们不会在他们的笔记本电脑上做一些工作,切换到桌面,然后想知道为什么他们已经在他们的笔记本电脑上注销了(我们不允许多个同时登录同一个用户).

PHP中的会话设置是Debian默认值,并且未在.htaccess文件或其他任何位置更改.主要是:

session.cookie_lifetime    0
session.gc_divisor    100
session.gc_maxlifetime    1440
session.gc_probability    0
session.save_handler    files
session.save_path    /var/lib/php5
session.use_cookies    On
Run Code Online (Sandbox Code Playgroud)

Debian通过cron作业删除会话,而不是使用PHP的垃圾收集器,这就是为什么gc_probability被设置为0.我们运行的PHP版本是:PHP 5.2.6-1 + lenny13与Suhosin-Patch 0.9.6.2(cli) (Lenny的最新版本,我们很快就会升级到Squeeze,但我不认为这是导致问题的原因).

我们使用Zend_Session来管理会话,并在每个页面上创建一次Zend_Session_Namespace实例,从而自动调用session_start().通过在注销页面上调用Zend_Session :: destroy()来清除会话,因此用户应该注销的唯一方法是:

  • 如果他们明确地点击了注销链接(我们会在发生这种情况时进行记录,并且似乎不会出现浏览预先获取页面并因此将用户注销的情况).
  • 如果他们让会话处于非活动状态超过24分钟,那么Debian可能会删除他们的会话(有一个cron作业每半小时运行一次,删除所有未经修改超过24分钟的会话).
  • 如果他们关闭浏览器,将删除其到期时间为0的会话cookie.

查看用户是否已登录的检查包括:

  • 他们有一个有效的会话(通过查看我们是否可以访问$ zsession-> user_id来检查).
  • 会话表中有一行具有匹配的用户ID和会话ID,这是在不到一小时前最后更新的.我们在注销时删除了这一行,这样即使会话仍然存在于磁盘上,也没有人可以在不登录的情况下访问该帐户.

任何人都可以建议我可以试试的其他事情

编辑:我根据评论留下的一些额外的事情:

  • 设置session.cookie_domain:这似乎在PHP中有非常奇怪的行为.如果我没有设置此变量并将其保留为默认值''(空字符串),则对www.domain.com的请求将生成www.domain.com的cookie.但是,如果我将cookie_domain设置为"www.domain.com",则cookie的域名为".www.domain.com"(注意引导点,这意味着对www.domain.com以下的所有内容都有效,例如subsite.www .domain.com).
  • 设置session.cookie_lifetime:PHP似乎没有更新每个请求的到期时间,因此如果我将cookie_lifetime设置为3600,cookie将在用户首次访问网站一小时后到期,即使他们登录并经常使用它.

编辑2:基于人们提出的其他问题:

  • 该站点托管在数据中心的单独VLAN中.访问该站点的任何人都不在该站点的同一网络上.
  • 没有使用IP身份验证,也不会在会话过程的任何部分使用客户端的IP地址(例如,如果用户的下一个请求来自不同的IP,我们不会将会话附加到IP地址并阻止用户) .

pwa*_*ing 2

最后,答案是废弃会话并编写我自己的非常简单的 cookie 代码,该代码与会话的不同之处如下:

  1. 将哈希值(有点像会话 ID)存储在数据库中而不是文件中。
  2. 将 cookie 设置为从现在起 3600 秒后过期(在每个页面上更新)而不是 0 秒(后者似乎会给 IE 用户带来问题,尽管我永远无法复制它)。
  3. 仅在用户登录或正在登录时发送 cookie 标头。

这不是一个理想的情况,因为需要重新发明轮子,但我的小解决方案似乎可以在 PHP 会话无法工作的地方工作,并且拥有一个工作站点是最重要的。