Welcome Guest, Not a member yet? Register   Sign In
Users lose CI session randomly and have to delete local cookie prior to logging in again
#1

[eluser]echadwickb[/eluser]
I am having a time with the sessions class in CI. Users get randomly logged out in one of my apps, and are unable to log back in until they remove the local cookie from their machine.

Server Environment:

IBM i V6R1
DB2 (using db2c driver)
PHP via CGI in Apache (or whatever the heck Zend Server is doing behind the scenes)
CI 1.7.2 in production (2.0 in development)

Clients: Chrome 8/IE 8/Firefox 3.x

Either sess_destroy() is not running or setcookie() within sess_destroy() is failing to invalidate the local cookie. I have a feeling that I'll be coming up with a solution as soon as I post this entry, but troubleshooting tips are much appreciated.
#2

[eluser]echadwickb[/eluser]
OK. I may have found and fixed the problem, though I need to do more testing to be sure. In sess_read(), CI checks the database for a matching session. If the query returns 0 rows, CI kills the session:
Code:
$query = $this->CI->db->get($this->sess_table_name);

// No result?  Kill it!
if ($query->num_rows() == 0)
{
    $this->sess_destroy();
    return FALSE;
}

num_rows() calls db2_num_rows, which according to php.net, does not return a row count for select statements. Instead, it returns -1 regardless of the results found. $query->num_rows() never equals 0, which means the session is never destroyed, which means the user gets stuck in a endless loop until the local cookie is removed.

As a solution, I extended the session class and overrode sess_read() to use the following logic instead:
Code:
if (count($query->result()) == 0)
{
    $this->sess_destroy();
    return FALSE;
}

I think the bigger issue here is db2, specifically on i, does not play well with ActiveRecord. When I get a breather on my projects, I'd like to build and improve on the excellent db2c driver to tackle some of these "gotchas". DB2 on i has been a lot of fun to work with. I'd love to see more adoption in the CI community.

Hope this helps someone else.
#3

[eluser]Firsh[/eluser]
I don't know about DB2 but does this also apply to me, I'm using it with a simple MYSQL installation, and basically using sessions through the cart class.

My program allows file uploads and stores these in a db with last_activity time. If the files haven't been used for a specific, the script removes the files. This cleaner runs as an ajax request after every page load.

I think separating normal sessions and these 'file sessions' is good, because if the files have been used the server will need to keep them at all costs, while the regular session can be destroyed.

My question is, when do the regular sessions get destroyed? If the users visit the page again, it removes their old one? Or does any new page load strips off old sessions automatically? Because if the site has a lot of non-returning visitors and the session destroying waits for a re-visit, then a lot of sessions would be stored in the DB which is not good.

My "file session" handler clears EVERY expired-anyway sessions. I'd like this behavior on CI sessions as well.
#4

[eluser]echadwickb[/eluser]
I may be misunderstanding your question, but I believe CI runs db sessions cleanup every time ANY user visits the website. Even if a user visits your website and never returns, any subsequent user's visit will clear that one time user's expired sessions.

Anybody want to back me up on this?
#5

[eluser]Firsh[/eluser]
[quote author="echadwickb" date="1296247310"]I may be misunderstanding your question, but I believe CI runs db sessions cleanup every time ANY user visits the website. Even if a user visits your website and never returns, any subsequent user's visit will clear that one time user's expired sessions.

Anybody want to back me up on this?[/quote]

Yeah this is what I'd like to know for sure. Because then I could move my file removal call to the sess_destroy() of CI's sessions. So I can avoid that auto ajax call.

Edit: SOLVED, It does not remove garbage sessions with each visit, it only includes some randomness to do it less often. But that runs on every page load, that's true. I was able to disable that and move my cleaning functions into MY_Sessions class.




Theme © iAndrew 2016 - Forum software by © MyBB