title: CodeIgniter 2.2-Stable Session Keeps On Expiring
body: <p>This has been a common issue over the last 2-3 years it appears, but the fixes I've been able to wrestle up don't seem to work.  Is anyone using CI 2.2-stable (pulled as of Oct 29/2014) that they've been able to prevent the session expiring frequently?</p>
  
  <p>This is how I'm setting and checking the session:</p>
  
  <p>Login</p>
  
  <pre><code>// User session data
  $user_session = array(
      'user' =&gt; $user,
      'start_time' =&gt; $_SERVER['REQUEST_TIME']
  );
  
  // Create user session
  $this-&gt;session-&gt;set_userdata( $user_session );
  </code></pre>
  
  <p>MY_Controller inherited by all controllers so redirected if session not found:</p>
  
  <pre><code>function __construct() 
  {
      parent::__construct();
  
      // Perform base check to make sure user is authenticated
      if( !$this-&gt;session-&gt;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
  </code></pre>
  
  <p>So I'm only checking the existence of the session data, and am not using the session_id directly.  Through stubbing the Session.php library, it seems to enter sess_read() line 135, and have no issues until it checks the num_rows() returned from query of the database on line 235, then it destroys the session.</p>
  
  <p><strong>UPDATE 1</strong></p>
  
  <p>It appears to be a similar to this <a href="https://stackoverflow.com/q/7980193/1148107">issue</a> and summed up very well <a href="https://degreesofzero.com/article/fixing-the-expiring-session-problem-in-codeigniter.html" rel="nofollow noreferrer">here</a>, but still doesn't seem to solve the issue as mentioned <a href="https://github.com/bcit-ci/CodeIgniter/issues/3084" rel="nofollow noreferrer">here</a>, which mentions changing the core.  But even so this solution doesn't work for single page applications, since the session will expire with all server requests being AJAX.</p>
  
  <p><strong>UPDATE 2</strong></p>
  
  <p>I added my temporary solution below if anyone has any suggestions or critiques, but the same issue still occurs, just less often.  Which makes sense since the outgoing request marked to update the session that updates the cookie, may have simultaneous requests being sent along side it, which don't have the right cookie since it updates just prior to them getting processed.  It appears to have just reduced the frequency a small bit.  The frequency could be further reduced possibly by setting a heart beat keep alive request that is the only request that updates the session, but it still wouldn't fix the issue from occurring.</p>
  
  <p><strong>TEMPORARY SOLUTION</strong></p>
  
  <p>Using the fix suggested in the update, and leveraging AngularJS, which I'm running client-side.  I ended up adding an interceptor that contains a $timeout, which only attaches a custom header on a request every 1 hour to update the session, and added the check for the header into the suggested fix for non-SPAs, and it seems to work.</p>
  
  <p>Fix Client-Side</p>
  
  <pre><code>.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;
  }])
  </code></pre>
  
  <p>Fix on Server-Side</p>
  
  <pre><code>function sess_update()
  {
      // Check for AJAX request and keep-alive header before updating session
      if( !$this-&gt;CI-&gt;input-&gt;is_ajax_request() &amp;&amp; 
          isset(apache_request_headers()['CodeIgniter'])  ) 
      {
          return parent::sess_update();
      }
  }
  </code></pre>