Dvir Levy
Dvir Levy

Reputation: 8128

Codeigniter sessions die

After a little bit of use (25min - 1.5 hour) in my system, users experience a kick. For some reason my sessions are kind of dyeing. I think that the cookie on the client side somehow loses the session ID and creates a new one. I am saving my session data on Database.

This is my session conf:

        $config['sess_cookie_name']     = 'v2Session';
        $config['sess_expiration']      = 32400; //session will be 9 hours, for a shift.
        $config['sess_expire_on_close'] = FALSE;
        $config['sess_encrypt_cookie']  = TRUE;
        $config['sess_use_database']    = TRUE;
        $config['sess_table_name']      = 'ci_sessions';
        $config['sess_match_ip']        = TRUE;
        $config['sess_match_useragent'] = TRUE;
        $config['sess_time_to_update']  = 300;

Now, when I look in the DB I see multiple sessions for each user. Each kick means a new session and the old session is not deleted until it expires. When the session "detaches" the users need to login again.

Any help troubleshooting this will be appreciated.

EDIT:

So after some research I have noticed that the sessions die because the session_id that is saved in the cookie and the session_id that is saved in the database do not match. I suspect that this happens when the user loads 2 pages each on a different tab/window. One load happens just when the session updates the session_id and the second load (which kills the session) with the old session_id. The system looks for the session in the database and doesn't find it. Result: Kick from the system + mad user.

Has anybody experienced this? and does anyone have an idea on how to fix this?

Upvotes: 10

Views: 9119

Answers (7)

Syed Waqas Bukhary
Syed Waqas Bukhary

Reputation: 5340

I was having the same problem running several applications under one CI installation. After several hours of line by line debug using xdebug, I found that each application in Codeigniter was having it's separate session. To resolve the error i provided separate name in each config.php file.

File one,

$config['sess_cookie_name']     = 'ci_session1';

File two

$config['sess_cookie_name']     = 'ci_session2';

File Three

$config['sess_cookie_name']     = 'ci_session3';

Upvotes: 0

Keval Domadia
Keval Domadia

Reputation: 4763

Short answer.

Do not start session at multiple instances., just check for existing ones, if we are talking about Authorization, then kick the user to AuthLogin page if Session does not exist. Create a Auth class / library and let it handle things. If the session does not exist, it will ask to create another.

Those are not 'multiple' sessions, the unique Session ID is statistically random string with very strong entropy, hashed with MD5 for portability, and regenrated (by default) every five minutes)

-- Check here under How do Sessions work?

When you perform session_destroy, it destroys sessions (multiple or single) related to the user, from database and also expires the cookie. Yes, bad design, I know!

From your EDIT of question

So after some research I have noticed that the sessions die because the session_id that is saved in the cookie and the session_id that is saved in the database do not match. I suspect that this happens when the user loads 2 pages each on a different tab/window. One load happens just when the session updates the session_id and the second load (which kills the session) with the old session_id. The system looks for the session in the database and doesn't find it.

Opening page in multiple tabs = Refresh on single tab.

Are you setting Sessions without checking about their existence? Please share your script.

I will keep an eye on this answer until we have figured this.

Yes, I had similar issue, it turned out that I used to set sessions without checking if they already existed and everytime, I created them, they over-lapped the Session (cookie) in the browser and created another row in database. It sounds like you're facing the same issue?

Ugly hack

Set this as your config:

    $config['sess_cookie_name']     = 'v2Session';
    $config['sess_expiration']      = 32400; //session will be 9 hours, for a shift.
    $config['sess_expire_on_close'] = FALSE;
    $config['sess_encrypt_cookie']  = TRUE;
    $config['sess_use_database']    = TRUE;
    $config['sess_table_name']      = 'ci_sessions';
    $config['sess_match_ip']        = TRUE;
    $config['sess_match_useragent'] = TRUE;
    $config['sess_time_to_update']  = 32400; // Session will update in 9 hours.

This is one-of-a-kind issue... However, on analyzing that sessions are mis-matching with database, it clearly indicates that upon sess_time_to_update, database might not be updating the relevant id... However, this solution would still be an assumption unless you try it.

Upvotes: 4

quickshiftin
quickshiftin

Reputation: 69731

From the docs under How do Sessions work?

When a page is loaded, the session class will check to see if valid session data exists in the user's session cookie. If sessions data does not exist (or if it has expired) a new session will be created and saved in the cookie. If a session does exist, its information will be updated and the cookie will be updated. With each update, the session_id will be regenerated.

Have you tried using the Code Igniter logging feature to see if the session module is purposely creating new sessions? More specifically, you probably want to do some debugging against the CI_Session class (system/libraries/Session.php).

There are 2 spots in sess_read where CI will determine there is no current session. If you enable logging, per the docs, you can see if CI is hitting these conditions

CI_Session::sess_read (condition 1)

// Fetch the cookie
$session = $this->CI->input->cookie($this->sess_cookie_name);

// No cookie?  Goodbye cruel world!...
if($session === FALSE)
{   
    log_message('debug', 'A session cookie was not found.');
    return FALSE;
}

CI_Session::sess_read (condition 2)

// encryption was not used, so we need to check the md5 hash
$hash    = substr($session, strlen($session)-32); // get last 32 chars
$session = substr($session, 0, strlen($session)-32);

// Does the md5 hash match?  This is to prevent manipulation of session data in userspace
if ($hash !==  md5($session.$this->encryption_key))
{
    log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.');
    $this->sess_destroy();
    return FALSE;
}  

I would guess at the first block, since you say the previously generated sessions are still hanging out in the database upon inspection. But definitely consider the logging feature and debugging the CI_Session class.

Upvotes: 0

Robert Trzebiński
Robert Trzebiński

Reputation: 1357

I've had the same problem, this config state finally helped:

$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 604800; // 604800 = 1 week
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie'] = FALSE;
$config['sess_use_database'] = TRUE;
$config['sess_table_name'] = 'ci_sessions';
$config['sess_match_ip'] = TRUE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update'] = 604800; // 604800 = 1 week

sess_time_to_update must be same as sess_expiration

sess_encrypt_cookie must be FALSE

Upvotes: 0

Ripa Saha
Ripa Saha

Reputation: 2540

I am also an codeigniter developer. I have also applied below code in my application:-

$config['sess_cookie_name']     = 'ci_session';
$config['sess_expiration']      = 300; // 7200
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie']  = true;
$config['sess_use_database']    = true;
$config['sess_table_name']      = TBL_SESSION;
$config['sess_match_ip']        = FALSE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update']  = 300;

In my application , after each 5 minute , session will expire. I am using table tbl_session for saving the record. Considering the below 2 condition , it's working perfectly for my application:-

1) opening application in firefox mozilla at 10:55 pm then it will take You in login screen at 11:00 pm.

2) at the same time , opening application in chrome browser at 10:56 pm  then it will take You in login screen at 11:05 pm.

1 thing to remember - the above code will be in your config.php and in each controller of Your application , there will be a checking for session activeness.

Upvotes: 1

Youssef Subehi
Youssef Subehi

Reputation: 2870

why don't you try this:

  1. Check if user has an active session IF Session is active = Nothing to do everything is fine

now if user don't have an active session, you need to do 2 things

  1. get the user cookies and if there is cookies you make the session start again and the user will be fine and logged in directly with depending on cookies he have

B. if the session is not active and there is not cookies, you need to take him to login page

here is an example

<?php
$expire=time()+60*60*24*30;
setcookie("user", "Login_USERNAME", $expire);
?>

In the example above the expiration time is set to a month (60 sec * 60 min * 24 hours * 30 days).

ok now you should get the cookies

    <?php
///Check if session alive or not
if (!empty($_SESSION['user'])){
     //Do Nothing the user is logged in 

    }
///There is Cookies BUT No Session
elseif (isset($_COOKIE["user"]) && empty($_SESSION['user'])){
      // Here you can see that there is cookies on the user PC and at the same time the Session is Not active so you should make session start and make user auto login again
    }

///There is no Cookies and Session is not alive
    elseif (!isset($_COOKIE["user"]) && empty($_SESSION['user'])){
      // Here you can see that there is No cookies and at the same time the Session is Not active so you should take user to login page
    }
?>

Thats it and you need to arrange it with your own code but this is the method to done it !

Note: Make Sure on user Logout to clear cookies so it won't auto login again.

Upvotes: 0

dev.bashar
dev.bashar

Reputation: 181

you can use basic php code

ini_set('session.gc_maxlifetime', 32400);

Upvotes: -1

Related Questions