Cannot retrieve session id using session class in CodeIgniter

10,331

Solution 1

What's your session cookie expiration set to? There is a known bug in CodeIgniter where, if you stay on a page that makes AJAX requets past the cookie expiration, it will reset the session id in the database, but will not be able to set it in the browser cookie because it's an asynchronous request. This causes there to be a disconnect on the next non-asynchronous GET request, leading to the session library calling sess_destroy(). If this sounds like your situation, let me know. Otherwise, provide more detail, please.

Edit: I should, perhaps, also include the fix for this bug here. Create a file in /application/libraries called "MY_Session.php" (if it doesn't already exist). In there you can paste this:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
* Session Class Extension
*/
class MY_Session extends CI_Session {
   /*
    * Do not update an existing session on ajax calls
    *
    * @access    public
    * @return    void
    */
    function sess_update() {
        if ( !isAjax() ){
            parent::sess_update();
        }
    }
}
?>

That isAjax() function is a helper I have in /application/helpers/isajax_helper.php that looks like this:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* is_ajax_call
*
* Determines if the current page request is done through an AJAX call
*
* @access    public
* @param    void
* @return    boolean
*/
if ( ! function_exists('isAjax')) {
    function isAjax() {
        return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
    }
}
?>

Which is referenced in my config file like this:

$autoload['helper'] = array('otherhelper1', 'isajax', 'otherhelper2');

Solution 2

not possible. The Session class does not utilize native PHP sessions.

best practice I recommend you

contoller contain uploadpage {
    function index(){
        $dataview['session_id'] = $this->secureUpload();
        $this->load->view('upload',$dataview);
    }
    function secureUpload(){
        $user_id =  $this->session->userdata('cuser_id');
        $md5pass = $this->basemodel->_getEncrypPassFromDb($user_id);
        $time =time();
        $session = md5($user_id.$time.$md5pass)."x".$user_id."x".$time;
        return $session;
    }
}

upload page

('#swfupload-control').swfupload({
    post_params: {"PHPSESSID": "<?=session_id?>"} ,

this way decryp you secure code

       function upload_function(){

            list($session2, $user_id, $time) = explode("x", $session);
    $this->load->library('upload', $config);
    $md5pass = $this->basemodel->_getMD5pass($user_id);
    $session_server = md5($user_id.$time.$md5pass)."x".$user_id."x".$time;

    if($session_server == $session){
             upload file by flash upload
            }

}

Solution 3

By default, CI creates a new sessionid in a defined interval. Look at the config to see the default value (I believe it's 5 minutes). So $this->session->userdata('session_id') will always contain a different ID but CI still is able to know who you are.

I ran into the problem for the exact same reason. I know why the CI guys created this session refreshment but I feel like it is making things more complex. You can override this behaviour in your config by simply entering a higher value for the session refresh.

In one of my apps, it looks like this:

$config['sess_expiration']  = 7200;
//$config['sess_time_to_update'] = 300;
$config['sess_time_to_update'] = $config['sess_expiration'];

This way, I'm able to use sessions as I would do without the framework.

Solution 4

I was just having this problem, ajax calls destroying my logged in user session. Here's @treeface solution with CI 2.1.2 per Mr. Sturgeon's suggestion. I guess the input and load libraries are not autoloaded in CI_Session, so I had to get the instance of the CI object to make this work.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
* Session Class Extension
*/
class MY_Session extends CI_Session {

    protected $_CI;

/*
* Do not update an existing session on ajax calls
*
* @access    public
* @return    void
*/
function sess_update() {

    $this->_CI =& get_instance();

        if ( !$this->_CI->input->is_ajax_request() ){
            parent::sess_update();
       }
   }
}
Share:
10,331
mehdi
Author by

mehdi

Updated on June 05, 2022

Comments

  • mehdi
    mehdi about 2 years

    i have this code in my controller

    class Upload_center extends Controller 
    {
        function __construct()
        {
            parent::Controller();
            $this->load->model('auth_model') ;
            if(!$this->auth_model->authorize())
            {
                redirect('login');
    
            } 
    
        }
    

    and I have this code in my view

    $('#swfupload-control').swfupload({
        upload_url: "<?=base_url()?>index.php/upload_center/upload",
        file_post_name: 'fileupload',
        file_size_limit : "200000000",
        file_types : "*.zip;*.rar;*.pdf;*.doc;*.docx;*.mp3;*.avi;*.wmv;*.docx;*.jpg;*.jpeg;*.JPG;*.JPEG;*.png;*.gif;*.bitmap;",
        file_types_description : "zip files ",
        post_params: {"PHPSESSID": "<?=$this->session->userdata('session_id');?>"} ,
        file_upload_limit : 1,
        flash_url : "<?=base_url()?>js/jquery-swfupload/js/swfupload/swfupload.swf",
        button_image_url : '<?=base_url()?>js/jquery-swfupload/js/swfupload/wdp_buttons_upload_114x29.png',
        button_width : 114,
        button_height : 29,
        button_placeholder : $('#button')[0],
        debug: false
    

    I want the user to upload their files after login, so I have a method that needs users to login before proceeding to upload files. Although I'm using flash uploader in my view, I think it doesn't pass the session value and PHP thinks the user is not logged in and it redirects him to the login page. I send phpsessionid by post but still no goes.

  • Phil Sturgeon
    Phil Sturgeon over 12 years
    You can now [since 2.0.x] use $this->input->is_ajax_request() instead of creating isAjax().