Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

session expires randomly after 5-10 mins #1

Open
kingster opened this issue Jun 16, 2011 · 12 comments
Open

session expires randomly after 5-10 mins #1

kingster opened this issue Jun 16, 2011 · 12 comments

Comments

@kingster
Copy link

I am using this for my website, normally it would work fine , but after 5-10 mins randomly it would expire the session. I have set session timeout value to 2 days but still then this happens

my current config

$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 1209600;
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie'] = TRUE;
$config['sess_use_database'] = FALSE;
$config['sess_table_name'] = 'ci_sessions';
$config['sess_match_ip'] = FALSE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update'] = 300;

/*
Memcached Session Variables
--------------------------------------------------------------------------

|
|
| "session_storage" = where you will be storing your session data. Accepts "memcached", "database", "cookie"
| "memcache_ports" = the port that you will connect to memcache on
| "memcached_nodes" = array of IP addresses of Memcached nodes
|
|
*/
$config['session_storage'] = 'memcached';
$config ['memcached_port'] = '11211';
$config['memcached_nodes'] = array('127.0.0.1');

can u please help me to fix this issue? I cant get anything reason for this behaviur

@pierskarsenbarg
Copy link
Owner

Yeah that's the reason it's not production ready yet. There's a link in the README file which explains it.

@kingster
Copy link
Author

seems that it is due to memcache miss, maybe you should implement a failover mechanism ?

@dennisvdvliet
Copy link
Contributor

I think this is related to the sess_write() function. When you write user_data to the session the session_id is not written to memcache.

When the class fetches the key from memcache there is not session_id and thus it will fail and log you out.

 case 'database':
            // Run the update query
            $this->CI->db->where('session_id', $this->userdata['session_id']);
            $this->CI->db->update($this->sess_table_name, array('last_activity' => $this->userdata['last_activity'], 'user_data' => $custom_userdata));
            break;
        case 'memcached':
            $this->memcache->replace("user_session_data" . $this->userdata['session_id'], array('last_activity' => $this->userdata['last_activity'], 'user_data' => $custom_userdata), false, $this->sess_expiration);
            log_message('debug', 'session written to memcache');
            break;
    }

I'm testing a fix right now

@kingster
Copy link
Author

@dennisvdvliet: Did u find any solution ? Let me know! I am eagerly waiting for the solution!

@dennisvdvliet
Copy link
Contributor

//rebuild array
$save  = array(
            'session_id' => $this->userdata['session_id'],
            'ip_address' => $this->CI->input->ip_address(),
            'user_agent' => substr($this->CI->input->user_agent(), 0, 50),
            'last_activity' => $this->now,
            'user_data' => $custom_userdata
        );

        switch ($this->session_storage) {
            case 'database':
                // Update the session ID and last_activity field in the DB if needed
                // set cookie explicitly to only have our session data
                $this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now, 'session_id' => $new_sessid), array('session_id' => $old_sessid)));
                break;
            case 'memcached':                
                // Add item with new session_id and data to memcached
                // then delete old memcache item
// save the whole array instead of updating
                $r = $this->memcached->set('user_session_data' . $new_sessid, $save,$this->sess_expiration+600);
                $this->memcached->delete('user_session_data' . $old_sessid);

@kingster what i did to fix it is rebuild the session array and save that to memcached. See code snippet

@kingster
Copy link
Author

I think that $custom_userdata is not defined in this function instance ( sess_update() )
I think before the //rebuild array this needs to be added


I will test this and let u know, hope that this solves the problem :)

@dennisvdvliet
Copy link
Contributor

@kingster I tried that and that did not work on all occasions. The code I posted has been used for a couple of weeks since mid-september and people are not logged out anymore on our site.

But keep me posted

@kingster
Copy link
Author

This is for sess_update() function or sess_write() ??

@dennisvdvliet
Copy link
Contributor

@kingster I use it both

Sorry for the late reply

@kingster
Copy link
Author

Hi

Can you send me your file at kinshuk1989[at]gmail[dot]com or atleast your copy in github please? I tried but mine didnt work.

@agustinprod
Copy link
Contributor

@kingster
The solution to this bug, just replace your sess_update with:

function sess_update() {
        // We only update the session every five minutes by default
        if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now) {
            log_message('info','not enough time before update');
            return;
        }
        log_message('info','MC defo need to update session');

        // Save the old session id so we know which record to
        // update in the database if we need it
        $old_sessid = $this->userdata['session_id'];
        $new_sessid = '';
        while (strlen($new_sessid) < 32) {
            $new_sessid .= mt_rand(0, mt_getrandmax());
        }

        // To make the session ID even more secure we'll combine it with the user's IP
        $new_sessid .= $this->CI->input->ip_address();

        // Turn it into a hash
        $new_sessid = md5(uniqid($new_sessid, TRUE));
        log_message('info','session id generated');
        // Update the session data in the session data array
        $this->userdata['session_id'] = $new_sessid;
        $this->userdata['last_activity'] = $this->now;

        // _set_cookie() will handle this for us if we aren't using database sessions
        // by pushing all userdata to the cookie.
        $cookie_data = NULL;

        $cookie_data = array();
        $mem_data = array();
        $cookie_keys = array('session_id', 'ip_address', 'user_agent', 'last_activity');
        foreach ($cookie_keys as $key) {
            $cookie_data[$key] = $this->userdata[$key];
        }
        foreach ($this->userdata as $key => $value) {
            if (in_array($key, $cookie_keys))
                continue;
            $mem_data[$key] = $this->userdata[$key];
        }
        $save  = array(
            'session_id' => $cookie_data['session_id'],
            'ip_address' => $cookie_data['ip_address'],
            'user_agent' => $cookie_data['user_agent'],
            'last_activity' => $this->now,
            'user_data' => $this->_serialize($mem_data)
        );

        switch ($this->session_storage) {
            case 'database':
                // Update the session ID and last_activity field in the DB if needed
                // set cookie explicitly to only have our session data
                $this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now, 'session_id' => $new_sessid), array('session_id' => $old_sessid)));
                break;
            case 'memcached':                
                // Add item with new session_id and data to memcached
                // then delete old memcache item
                $this->memcached->set('user_session_data' . $new_sessid, $save, $this->sess_expiration);
                log_message('info', 'MC new session added' . $this->sess_expiration);
                $this->memcached->delete('user_session_data' . $old_sessid);
                log_message('info', 'MC old session deleted');

                break;
        }

        unset($mem_data);

        // Write the cookie
        $this->_set_cookie($cookie_data);
    }

@kevosomi
Copy link

kevosomi commented Sep 6, 2014

clockwork! This saved me the pain of having to figure out what was messing my cookies and sessions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants