应用程序的 PHP 代码是否始终可以 read/delete 访问同一服务器上的会话文件?

Will PHP code of an app always have read/delete access to session files on the same server?

为了我的 Joomla! 3.8+ 扩展我需要能够找到并删除(取消链接)PHP 会话文件(名为 'sess_' + 会话 ID),这些文件将存储在 session_save_path 中,例如/tmp。我知道是 PHP 存储会话文件,即不是 Joomla! (Joomla!会话处理程序设置为 'PHP') 我的问题: PHP 会话文件是通过使用 Joomla 创建的吗?网站总是 read/write 可以通过我的扩展程序的 PHP 代码访问,该代码是同一个 Joomla!安装?

补充:后来我发现,我的问题中省略了'always'这个词,现在我添加了

补充:更深入地解释我正在努力实现的目标。 正如我所说,我有一个 Joomla!站点,用户可以在其中登录。 该问题仅适用于 Joomla!配置为会话处理程序设置为 'PHP'(而不是 'database')。当 Session Handler 为 'database' 时,没有问题。

基本上,我想实现以下目标(Joomla! 会话处理程序设置为 'PHP'):

1> A user opens browser A and logs into the website and Joomla! records the related session ID plus user ID in a database.

2> The same user opens a different browser B (maybe at a different IP) and wants to log into the same website.

3> Because user has already logged into the website through browser A, he/she is not allowed to log in again and will be presented a clickable link that will destroy all his other sessions, including the one with browser A (we have recorded the session IDs of all the other sessions).

第 3 步中的 session_destroy() 只是起到了部分作用,因为在 Joomla!后端以及 Joomla!会话 table。虽然这不会干扰 Joomla!前端,它不干净,我想避免它,让它万无一失。 到目前为止,最好的解决方案是删除 PHP 会话文件(例如在目录 /tmp 中并命名为 'sess_....')。我已经对此进行了测试,并且效果很好。但是......它依赖于始终具有对 PHP 会话文件的删除访问权限(使用 session_save_path() 和 unlink($session_file_path)),这是我提出的问题的基础post编辑。 我发现 PHP 会话文件的删除并不总是可行的;这取决于提供商的 PHP 配置。由于这是我正在开发的商业应用程序,因此该过程必须适用于所有配置,即包括那些不允许对会话文件进行删除访问的配置。

我会继续寻找解决方案,找到后会 post 放在这里。

这取决于服务器设置。

  1. 查找用户PHP正在使用:How to check what user php is running as?

  2. 检查该用户对存储会话的文件夹的权限:Unix: How to check permissions of a specific directory?

  3. 需要时更改权限:https://serverfault.com/questions/105535/how-can-i-set-full-premissions-to-a-user-in-a-specified-dir

谢谢@Nigel 和@AgeDeO

通过反复试验,我发现答案是否定的,并非总是如此。 通过与一些商业 ISP 一起执行代码,我遇到了一个 ISP,他们不允许我删除处于默认位置的 PHP 会话文件。地点是 /var/lib/php5.

你想要的经常是可能的,但它会带来安全风险(试想:一个用户可以阅读会话文件,然后再知道它们属于谁,其他用户的也是如此),因此具有安全意识的 ISP 将努力防止这种情况发生。

因此,即使您设法做到这一点,如果 ISP 将来加强其安全性,也没有什么可以保证您的代码不会被破坏。这造成了一些维护上的不安。

更好的解决方案是使用 无效会话 ID.

的辅助 table

然后你写一个用户插件挂钩 onUserAuthorizationonUserLogout 事件。你也需要 onAfterInitialise

这个钩子会在初始化时检查当前会话ID是否已经失效;如果是,立即注销被触发。否则,更新其时间戳。

用户注销时,当前会话 ID 将从 table 中删除并销毁会话。

在新登录时,会发出有关其他会话正在打开的警告:如果登录成功,同一用户的所有其他会话将被标记为无效。

作为一项维护任务,所有时间戳早于最长会话生命周期的条目都可以安全地删除。