Codeigniter会话死了

时间:2013-12-03 15:16:04

标签: php codeigniter session

在我的系统中使用了一点点(25分钟 - 1.5小时)后,用户就会受到欢迎。出于某种原因,我的会议有点染色。我认为客户端的cookie以某种方式丢失会话ID并创建一个新的。我将会话数据保存在Database

这是我的会议conf:

        $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;

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

任何帮助解决此问题的帮助都将受到赞赏。

编辑:

经过一些研究后,我注意到会话因为session_id中保存的cookiesession_id中保存的database而失败比赛。我怀疑当用户在不同的选项卡/窗口上加载2个页面时会发生这种情况。当会话使用旧session_id更新session_id和第二次加载(杀死会话)时,就会发生一次加载。系统在database中查找会话但找不到它。 结果:从系统+疯狂用户中踢出来。

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

7 个答案:

答案 0 :(得分:4)

简短回答。

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

那些不是'多个'会话,唯一的会话ID是统计上随机的字符串,具有非常强的熵,用MD5进行散列以便于移植,并且每五分钟重新生成(默认情况下))

- Check here 会话如何运作?

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

来自您的问题编辑

  

经过一些研究后,我注意到会议因此而死   保存在cookie中的session_id和session_id   保存在数据库中不匹配。我怀疑这发生在   用户在不同的选项卡/窗口上加载2个页面。一个负载   恰好在会话更新session_id和第二个会话时发生   使用旧的session_id加载(杀死会话)。系统   在数据库中查找会话但找不到它。

在多个标签页中打开页面=在单个标签页上刷新。

你是在设置Sessions而不检查它们的存在吗?请分享你的剧本。

在我们想到这个之前,我会密切关注这个答案。

是的,我有类似的问题,原来我曾经设置会话而不检查它们是否已经存在,每次创建它们,它们在浏览器中重叠了Session(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 ...但是,这个除非你尝试,否则解决方案仍然是一个假设。

答案 1 :(得分:1)

我也是一名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分钟后,会话将过期。我正在使用table tbl_session来保存记录。考虑到以下两个条件,它适用于我的应用程序: -

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 中,并且在您的应用程序的每个控制器中,都会检查会话活动性。

答案 2 :(得分:0)

你为什么不试试这个:

  1. 检查用户是否有活动会话如果会话处于活动状态=无所事事
  2. 现在如果用户没有活动会话,则需要做两件事

    1. 获取用户cookie,如果有cookie,您可以重新开始会话,用户可以直接登录,具体取决于他拥有的cookie
    2. B中。如果会话未激活且没有cookie,则需要将他带到登录页面

      这是一个例子

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

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

      好的,现在你应该得到cookies

          <?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,以便它不会再次自动登录。

答案 3 :(得分:0)

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

$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

答案 4 :(得分:0)

来自{{3>} 会话如何运作?

  

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

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

sess_read中有2个点,其中CI将确定没有当前会话。如果启用日志记录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 类。

答案 5 :(得分:0)

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

文件一,

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

文件二

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

文件三

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

答案 6 :(得分:-1)

你可以使用基本的PHP代码

ini_set('session.gc_maxlifetime', 32400);