【问题标题】:Codeigniter sessions dieCodeigniter 会话终止
【发布时间】:2013-12-19 17:29:18
【问题描述】:

在我的系统中使用一段时间(25 分钟 - 1.5 小时)后,用户体验到了刺激。出于某种原因,我的课程有点像染色。我认为客户端的cookie不知何故丢失了会话ID并创建了一个新的。我将会话数据保存在Database。

这是我的会话配置:

        $config['sess_cookie_name']     = 'v2Session';
        $config['sess_expiration']      = 32400; //session will be 9 hours, for a shift.
        $config['sess_expire_on_close'] = FALSE;
        $config['sess_encrypt_cookie']  = TRUE;
        $config['sess_use_database']    = TRUE;
        $config['sess_table_name']      = 'ci_sessions';
        $config['sess_match_ip']        = TRUE;
        $config['sess_match_useragent'] = TRUE;
        $config['sess_time_to_update']  = 300;

现在,当我查看数据库时,我看到每个用户都有多个会话。每次踢都意味着一个新会话,并且旧会话在过期之前不会被删除。当会话“分离”时,用户需要再次登录。

任何解决此问题的帮助将不胜感激。

编辑:

因此,经过一些研究,我注意到会话终止是因为保存在 cookie 中的 session_id 和保存在 database 中的 session_id 不匹配。我怀疑当用户在不同的选项卡/窗口上加载 2 个页面时会发生这种情况。仅当会话更新session_id 时发生一次加载,而第二次加载(终止会话)使用旧的session_id。系统在database 中查找会话,但没有找到。 结果:踢出系统+疯狂用户。

有人经历过吗?有没有人知道如何解决这个问题?

【问题讨论】:

  • 既然您将sess_match_ip 设置为true - 您是否检查过他们的IP 是否仍然相同?
  • 我同意@CBroe - 我会将 sess_match_ip 更改为 false。我总是把它当作假的,我从来没有遇到过这种问题。您的大多数用户几乎肯定会使用动态 IP 地址(如果他们通过移动设备访问更是如此),因此您不应依赖匹配 IP 地址。
  • @CBroe - 我最近更改了sess_match_ip 以尝试解决这个问题。 @Matthew - 这是一个办公应用程序,我的大多数用户(90%)都在使用静态 IP。
  • 您是否尝试过调试 CI_Session 类,或启用日志记录以查看 CI 是否有意启动新会话?如果是这样,您可能会从那里回溯以找出发生了什么。

标签: php codeigniter session


【解决方案1】:

你可以使用基本的php代码

ini_set('session.gc_maxlifetime', 32400);

【讨论】:

  • 对于 Codeigniter 我认为你必须同时设置
  • 这是不正确的。 CodeIgniter 的会话系统根本不使用 PHP 的原生会话。
  • 虽然不正确,但我们可以使用 CI 的本地会话... :)
【解决方案2】:

简短回答。

不要在多个实例上启动会话。,只需检查现有的,如果我们正在谈论授权,则如果会话不存在,则将用户踢到 AuthLogin 页面。 创建一个 Auth 类/库并让它处理事情。如果会话不存在,它会要求创建另一个。

那些不是“多个”会话,唯一的会话 ID 是具有非常强熵的统计随机字符串,使用 MD5 散列以实现可移植性,并且(默认情况下)每五分钟重新生成一次)

-- Check here 在 Sessions 如何工作?

下

当您执行 session_destroy 时,它会从数据库中销毁与用户相关的会话(多个或单个),并使 cookie 过期。是的,糟糕的设计,我知道!

来自您的问题编辑

所以经过一些研究后,我注意到会话结束是因为 session_id 保存在 cookie 和 session_id 是 保存在数据库中的不匹配。我怀疑这种情况发生在 用户在不同的选项卡/窗口上加载 2 个页面。一个负载 仅在会话更新 session_id 和第二个时发生 使用旧的 session_id 加载(终止会话)。系统 在数据库中查找会话,但没有找到。

在多个选项卡中打开页面 = 在单个选项卡上刷新。

您是否设置了会话而不检查它们的存在?请分享您的脚本。

我会密切关注这个答案,直到我们弄清楚这一点。

是的,我有类似的问题,原来我曾经设置会话而不检查它们是否已经存在,并且每次我创建它们,它们在浏览器中重叠会话(cookie)并在数据库中创建另一行.听起来您也面临同样的问题?

丑陋的黑客攻击

将此设置为您的配置:

    $config['sess_cookie_name']     = 'v2Session';
    $config['sess_expiration']      = 32400; //session will be 9 hours, for a shift.
    $config['sess_expire_on_close'] = FALSE;
    $config['sess_encrypt_cookie']  = TRUE;
    $config['sess_use_database']    = TRUE;
    $config['sess_table_name']      = 'ci_sessions';
    $config['sess_match_ip']        = TRUE;
    $config['sess_match_useragent'] = TRUE;
    $config['sess_time_to_update']  = 32400; // Session will update in 9 hours.

这是独一无二的问题...但是,在分析会话与数据库不匹配时,它清楚地表明在 sess_time_to_update 时,数据库可能不会更新相关的 id...但是,这除非您尝试,否则解决方案仍然是一个假设。

【讨论】:

  • Are you setting Sessions without checking about their existence? 是什么意思?加载网站时会创建一个会话(如果不存在),如果它没有登录标志,则用户将被定向到登录表单。在登录时,我将我的相关数据插入到会话中。为此,我只需执行:$this->session->set_userdata($user); 并检查我是否有实时会话,我只需执行:if(!$this->session->userdata('logged'))。它看起来很简单,看起来不应该失败。我不明白你想让我分享什么代码。?
  • 嗯...您的问题是关于验证用户并保持其稳定...我们中的许多人都在 CI 上工作过,它适用于我们所有人,这意味着 CI 核心没有问题...因此,如果有错误,它必须在您的代码中,您在其中进行身份验证...您是否玩过$this->session->all_userdata() 并检查过?
  • 另外,如果你不怀疑,我想看看你的 config.php ,请随意删除不打算公开查看的部分。
  • 我的config.php的session部分已经贴在问题里了,你对什么部分感兴趣?身份验证也可以工作,我向 Session.php 核心添加了一些日志记录,以查看它在哪里死亡,并且它总是在数据库检查 if ($query->num_rows() == 0) 处死亡 sess_read()。这可能是由于加载了辅助数据库$DB2 = $this->load->database($config,TRUE);?
  • 啊哈,现在我们接触基地!是的,伙计……它与辅助数据库有关。我们可以诊断和评估......这个应用程序有多少数据库?
【解决方案3】:

你为什么不试试这个:

  1. 检查用户是否有活动会话 IF 会话处于活动状态 = 无事可做,一切正常

现在如果用户没有活动会话,你需要做两件事

  1. 获取用户 cookie,如果有 cookie,您可以重新启动会话,用户会没事并直接登录,具体取决于他拥有的 cookie

B.如果会话不活跃且没有cookies,你需要带他到登录页面

这是一个例子

<?php
$expire=time()+60*60*24*30;
setcookie("user", "Login_USERNAME", $expire);
?>

在上面的示例中,到期时间设置为一个月(60 秒 * 60 分钟 * 24 小时 * 30 天)。

好的,现在你应该得到 cookie

    <?php
///Check if session alive or not
if (!empty($_SESSION['user'])){
     //Do Nothing the user is logged in 

    }
///There is Cookies BUT No Session
elseif (isset($_COOKIE["user"]) && empty($_SESSION['user'])){
      // Here you can see that there is cookies on the user PC and at the same time the Session is Not active so you should make session start and make user auto login again
    }

///There is no Cookies and Session is not alive
    elseif (!isset($_COOKIE["user"]) && empty($_SESSION['user'])){
      // Here you can see that there is No cookies and at the same time the Session is Not active so you should take user to login page
    }
?>

就是这样,你需要用你自己的代码来安排它,但这是完成它的方法!

注意:确保在用户注销时清除 cookie,使其不会再次自动登录。

【讨论】:

  • 这意味着从头开始编写会话类,这很麻烦。 CodeIgniters 类为我提供了所需的一切,而且我需要将会话存储在数据库中以进行远程断开连接和使用情况统计。
  • 不需要写你可以在IF里面调用类我确实给了你开始的基本代码,这是一个很好的开始方法,但是你需要修改它的方式适合您的代码
【解决方案4】:

我也是一名 codeigniter 开发人员。我还在我的应用程序中应用了以下代码:-

$config['sess_cookie_name']     = 'ci_session';
$config['sess_expiration']      = 300; // 7200
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie']  = true;
$config['sess_use_database']    = true;
$config['sess_table_name']      = TBL_SESSION;
$config['sess_match_ip']        = FALSE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update']  = 300;

在我的应用程序中,每 5 分钟后,会话将过期。我正在使用表 tbl_session 来保存记录。考虑到以下 2 个条件,它非常适合我的应用程序:-

1) opening application in firefox mozilla at 10:55 pm then it will take You in login screen at 11:00 pm.

2) at the same time , opening application in chrome browser at 10:56 pm  then it will take You in login screen at 11:05 pm.

要记住的一件事 - 上面的代码将在您的 config.php 中,并且在您的应用程序的每个控制器中,都会检查会话活动性。

【讨论】:

  • @Dvir Levy 对你有帮助吗?
【解决方案5】:

我也遇到了同样的问题,这个配置状态终于有帮助了:

$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 604800; // 604800 = 1 week
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie'] = FALSE;
$config['sess_use_database'] = TRUE;
$config['sess_table_name'] = 'ci_sessions';
$config['sess_match_ip'] = TRUE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update'] = 604800; // 604800 = 1 week

sess_time_to_update 必须与 sess_expiration 相同

sess_encrypt_cookie 必须为 FALSE

【讨论】:

    【解决方案6】:

    来自the docs 会话如何工作?

    当一个页面被加载时,会话类会检查是否有效 会话数据存在于用户的会话 cookie 中。如果会话数据 不存在(或者如果它已过期)将创建一个新会话 并保存在 cookie 中。如果会话确实存在,它的信息将 被更新并且cookie将被更新。每次更新时, session_id 将被重新生成。

    您是否尝试过使用 Code Igniter 日志记录功能来查看会话模块是否故意创建新会话?更具体地说,您可能想要对 CI_Session 类 (system/libraries/Session.php) 进行一些调试。

    sess_read 中有两个位置 CI 将确定当前没有会话。如果您启用日志记录,per the docs,您可以查看 CI 是否满足这些条件

    CI_Session::sess_read(条件 1)

    // Fetch the cookie
    $session = $this->CI->input->cookie($this->sess_cookie_name);
    
    // No cookie?  Goodbye cruel world!...
    if($session === FALSE)
    {   
        log_message('debug', 'A session cookie was not found.');
        return FALSE;
    }
    

    CI_Session::sess_read(条件 2)

    // encryption was not used, so we need to check the md5 hash
    $hash    = substr($session, strlen($session)-32); // get last 32 chars
    $session = substr($session, 0, strlen($session)-32);
    
    // Does the md5 hash match?  This is to prevent manipulation of session data in userspace
    if ($hash !==  md5($session.$this->encryption_key))
    {
        log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.');
        $this->sess_destroy();
        return FALSE;
    }  
    

    我猜是第一个块,因为您说之前生成的会话在检查时仍在数据库中。但一定要考虑日志功能和调试 CI_Session 类。

    【讨论】:

    • 我一直在记录并且 mt 会话都在这种情况下被破坏://没有结果?杀死它! if ($query->num_rows() == 0) 我不能把我的手指放在什么表弟这......
    • 太好了,那你就知道去哪里找了。通读代码,看起来数据库中没有匹配的结果。也许您在其他地方手动拨打sess_destroy?您可能想尝试扩展日志消息以帮助确定问题。如果您今天想尝试一下,我邀请您参加聊天。
    • Link 聊天。如果此线程上的其他人想要加入,请告诉我。
    【解决方案7】:

    我在一个 CI 安装下运行多个应用程序时遇到了同样的问题。在使用 xdebug 逐行调试几个小时后,我发现 Codeigniter 中的每个应用程序都有单独的会话。为了解决这个错误,我在每个 config.php 文件中提供了单独的名称。

    文件一,

    $config['sess_cookie_name']     = 'ci_session1';
    

    文件二

    $config['sess_cookie_name']     = 'ci_session2';
    

    文件三

    $config['sess_cookie_name']     = 'ci_session3';
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-31
      • 1970-01-01
      • 1970-01-01
      • 2016-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-16
      相关资源
      最近更新 更多