Codeigniter会话终止


Codeigniter sessions die

在我的系统中使用了一段时间(25分钟-1.5小时)后,用户会感到很兴奋。出于某种原因,我的课程有点染色。我认为客户端的cookie以某种方式丢失了会话ID,并创建了一个新的会话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;

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

如有任何疑难解答帮助,我们将不胜感激。

编辑:

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

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

简短回答。

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

这些不是"多个"会话,唯一的会话ID是统计上随机的字符串,具有非常强的熵,为了可移植性,使用MD5进行散列,并(默认情况下)每五分钟重新生成一次

--查看会话如何工作

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

从您的问题编辑

因此,经过一些研究,我注意到这些疗程会因为保存在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。然而,除非您尝试,否则此解决方案仍然是一种假设。

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

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

为什么不试试这个:

  1. 检查用户是否有活动会话if会话处于活动状态=无需执行任何操作即可

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

  1. 获取用户cookie,如果有cookie,您可以重新启动会话,用户将很好,并根据其拥有的cookie直接登录

B。如果会话未激活且没有cookie,则需要将他带到登录页面

这是一个的例子

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

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

好的,现在你应该得到饼干

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

我也遇到过同样的问题,这种配置状态最终起到了帮助作用:

$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

会话如何工作下的文档

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

您是否尝试过使用代码点火器日志记录功能来查看会话模块是否有意创建新会话?更具体地说,您可能想对CI_Session类(system/librarys/Session.php)进行一些调试

sess_read中有两个点,CI将确定不存在当前会话。如果您启用日志记录,根据文档,您可以看到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类。

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

文件一,

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

文件二

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

文件三

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

您可以使用基本的php代码

ini_set('session.gc_maxlifetime', 32400);