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?
This is how I'm setting and checking the session:
Login
// User session data
$user_session = array(
'user' => $user,
'start_time' => $_SERVER['REQUEST_TIME']
);
// Create user session
$this->session->set_userdata( $user_session );
MY_Controller inherited by all controllers so redirected if session not found:
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
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.
UPDATE 1
It appears to be a similar to this issue and summed up very well here, but still doesn't seem to solve the issue as mentioned here, 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.
UPDATE 2
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.
TEMPORARY SOLUTION
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.
Fix Client-Side
.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;
}])
Fix on Server-Side
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();
}
}