检测session_id(some-id)是否存在

时间:2011-11-17 11:55:00

标签: php sessionid

  

可能重复:
  Detect if PHP session exists

PHP手册似乎没有提供检查给定session_id是否存在的方法。例如,session_id()有一个可选的id参数,但它会替换现有的id而不是查找所需的方法:session_id_exists(some-id)

为什么我需要检查给定的session_id是否存在?用例是一种体育订阅服务,其中密码共享已成为一个问题。在登录时,我将用户的会话ID存储在数据库中,并使用它来与附加到给定userID的任何其他现有会话ID进行比较。

为了实现,我需要检查当前会话中是否存在收集的会话ID(密码共享的证明是同时登录多个用户)。

我认为有一种简单的方法可以实现这一目标......

4 个答案:

答案 0 :(得分:3)

你如何在index.php

的顶部做这样的事情
// Update current userid/session record with current timestamp
mysql_query("UPDATE sessions SET last_activity = CURRENT_TIMESTAMP() WHERE user = '$username' AND sid = '".session_id()."'");
// Search for multiple records with timestamp in the last 20 minutes where user id is the same
$result = mysql_fetch_assoc(mysql_query("SELECT COUNT(*) AS current_sessions FROM sessions WHERE user = '$username' AND last_activity > '".date('Y-m-d H:i:s', time() - 1200)."'"));
if ($result['current_sessions'] > 1) {
  // handle duplicates here
}

您可能不喜欢这种方法,因为它在每次页面加载时都涉及两个数据库查询,但它应该可以工作,并且可能比检查会话文件更有效。

答案 1 :(得分:0)

遵循CodeCaster的评论:

对于每个用户连接/断开连接,而不是检查PHP会话ID。会话到期,维护当前连接用户的列表(以及连接时间,IP等),例如在数据库表中。

因此,您将能够使用单个帐户检测多个连接。

您也可以尝试创建一个循环遍历所有会话文件的小脚本(如果您使用默认存储),请使用' unserialize()'在它上面并检查几个会话文件是否具有相同的用户标识符(假设您将它们存储到$_SESSION

编辑:由于这应该针对每个用户连接进行,因此数据库表方法(如CodeCaster建议的那样)似乎更好。

答案 2 :(得分:0)

您应该创建自己的会话状态实现,为您的用例提供所需操作的界面。

class SessionState
{
    public function idExists($id)
    {
        $gateway = new SessionGateway();
        $result = $gateways->searchById($id);
        # ... 
    }
}

如果您已经实现了详细信息,则只需使用应用程序中的对象即可。

答案 3 :(得分:0)

首先,这对防止密码共享的方法进行了很好的探索。

我根据每个请求跟踪用户活动的直觉反应(即@DaveRandom提出的2个查询解决方案)是啊啊,不!正如@CodeCaster指出的那样,可能是过早优化的情况,但是,嘿,我们有一个小的(几千)但狂热的用户群,对于曲棍球赛季的开始和比赛结果来说非常随意。这个网站有多年来一直运行不稳定,不想摇摇欲坠,这是一项付费服务​​,所以表现一定非常出色。

好的,解决方案:

apache用户对会话目录中的会话文件具有读/写访问权限。通过在登录时记录session_id,我们可以锁定共享密码帐户。成功登录后:

- Loop through stored session ids related to target account
- if /path/to/session-id-file not empty, increment login counter
- if login counter exceeds number of users allowed for a given plan:
- delete all session files related to target account
- lock the account and force a password reset

最小的开销,实施是蛋糕,问题解决了。

注意:我原本以为没有创建安全循环就无法访问会话目录文件;然而,事实并非如此(至少在我的CentOS 5版本中)。您无法获得与当前用户的会话无关的session_id,但您可以存储给定用户的会话ID,并且从任何用户的会话中访问存储其会话的会话文件(包括吹走文件)。关键是要使用会话ID来查找相应的/ path / to / session-file