【问题标题】:CodeIgniter 2.2-Stable Session Keeps On ExpiringCodeIgniter 2.2-Stable 会话不断过期
【发布时间】:2014-11-27 11:08:57
【问题描述】:

在过去的 2 到 3 年中,这一直是一个常见问题,但我能够努力解决的修复似乎不起作用。是否有人使用 CI 2.2-stable(截至 2014 年 10 月 29 日撤消)能够防止会话频繁过期?

这就是我设置和检查会话的方式:

登录

// User session data
$user_session = array(
    'user' => $user,
    'start_time' => $_SERVER['REQUEST_TIME']
);

// Create user session
$this->session->set_userdata( $user_session );

MY_Controller 由所有控制器继承,如果未找到会话则重定向:

function __construct() 
{
    parent::__construct();

    // Perform base check to make sure user is authenticated
    if( !$this->session->userdata( 'user' ) ) 
    {
        // If not logged in then return server response 403 allowing redirect
        // on the client-side using AngularJS interceptor
        show_error('No valid authenticated session', 403);
    }
} // END function __construct

所以我只是检查会话数据的存在,而不是直接使用 session_id。通过 stubbing Session.php 库,它似乎进入了 sess_read() 第 135 行,并且没有问题,直到它检查了第 235 行从数据库查询返回的 num_rows(),然后它销毁了会话。

更新 1

它似乎与issue 类似,并且总结得很好here,但似乎仍然没有解决here 提到的问题,其中提到了更改核心。但即便如此,此解决方案也不适用于单页应用程序,因为会话将过期,所有服务器请求都是 AJAX。

更新 2

如果有人有任何建议或批评,我在下面添加了我的临时解决方案,但同样的问题仍然会出现,只是不太常见。这是有道理的,因为标记为更新更新 cookie 的会话的传出请求可能会同时发送请求,这些请求没有正确的 cookie,因为它在它们被处理之前更新。它似乎只是稍微降低了频率。可以通过设置心跳保持活动请求来进一步降低频率,这是更新会话的唯一请求,但它仍然不能解决问题的发生。

临时解决方案

使用更新中建议的修复程序,并利用我在客户端运行的 AngularJS。我最终添加了一个包含 $timeout 的拦截器,它仅在每 1 小时一次的请求上附加一个自定义标头以更新会话,并将对标头的检查添加到针对非 SPA 的建议修复中,它似乎有效.

修复客户端

.factory('KeepAlive', ['$q', '$injector', '$timeout',
    function( $q, $injector, $timeout ) {

        var ticking = false;

        var service = {
            request: function( config ) {

                if( ticking === false ) {

                    // Set ticking to block keep-alive
                    ticking = true;

                    // Set timeout to unblock keep-alive on expiry
                    $timeout( function() {
                        ticking = false;
                    }, 6300000 ); // 105 minute time out

                    // Add keep-alive header to out-going request
                    config.headers = { 'CodeIgniter': 'Keep-Alive' };
                } 

                return config;   
            }
        }

        return service;
}])

在服务器端修复

function sess_update()
{
    // Check for AJAX request and keep-alive header before updating session
    if( !$this->CI->input->is_ajax_request() && 
        isset(apache_request_headers()['CodeIgniter'])  ) 
    {
        return parent::sess_update();
    }
}

【问题讨论】:

    标签: php codeigniter session codeigniter-2


    【解决方案1】:

    我正在使用 CI 2.2 并且会话运行良好,尽管我们在会话过期方面也遇到了困难:

    一个重要的考虑因素是 CI 频繁地重新生成 session_id 以防止会话固定攻击。所以不要在你的应用程序中直接使用 session_id,而是将其视为 CI 内部使用的东西。为自己生成另一个 id(这可能是第一个生成的 session_id)并将其存储在会话用户数据中。只要会话本身未过期,会话数据就会保留。

    if (!isset($this->session->userdata('sid')))  
      $this->session->set_userdata('sid', $this->session->userdata('session_id'));
    

    关于会话过期的设置有两种:

    • sess_expiration:整个会话本身到期

    • sess_time_to_update:session_id的过期和重新生成

    如果您将会话存储在数据库中,session_id 也会在那里更新。

    【讨论】:

    • 您好,当创建会话时,我实际上并没有直接使用 session_id。我已经更新了我如何使用它的问题,但由于数据库没有返回结果,它似乎破坏了会话。会话在一天内经常被删除,但我可以在日志中看到 sessionid 发生变化而没有丢失会话,所以它似乎是别的东西。
    猜你喜欢
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多