Welcome Guest, Not a member yet? Register   Sign In
[Solved] Various Session problems
#1

[eluser]fchristant[/eluser]
I am looking for some advice on CI Sessions. I have set it up to use my database for storing sessions, here are my settings:

Code:
$config['sess_cookie_name']        = 'pd_session';
$config['sess_expiration']           = 1209600; // 2 weeks
$config['sess_encrypt_cookie']    = true;
$config['sess_use_database']    = true;
$config['sess_table_name']        = 'sessions';
$config['sess_match_ip']        = FALSE;
$config['sess_match_useragent']    = TRUE;
$config['sess_time_to_update']         = 300;

I have created the sessions table as the documentation prescribes and I am autoloading the session class. Session data is coming in, so the basic setup seems to work. Still in practice I am experiencing some weird behavior:

1. Although I have configured the session to last for 2 weeks, I have users reporting that their session is lost. So far I have not been able to find a pattern in when and how it happens, but it happens.

2. The actual session data table does not look right to me. There is a very large amount of duplicates where both the ip and the hostname are the same, almost as if every time a new session is created. The help suggest to set IP matching to false. It is not clear to me under what conditions CI creates a new session record. And why does it never purge the table?

3. On my development environment, I see the Google bot dropping by, creating its own sessions. Is there a way to prevent this?

4. On my production environment (CentOS), the sessions table looks way different than on my dev environment (Debian). In production, all ips in the session table are set to 0.0.0.0 and all user agents are set to 0

I very much like the CI setup of secure and database driven sessions but I cannot get it to behave. I have no clue what I can do to fix this as the setup is so straightforward.
#2

[eluser]WanWizard[/eluser]
If your application using ajax calls?

1. If so, you need to extend the session class so that the session_id is not rotated every (in this case) 300 seconds. If this happens on an ajax call, the id in the database has changed, but the browser never received the updated cookie. Search here for IS_AJAX to find the solution.

2. The cause of this could be in 1. Also, remove the underscore from the cookie name, Internet Explorer doesn't like it.

3. No, a request is a request, doesn't matter where it comes from. Blocking bots from creating sessions might even break your code (that might expect a valid session).

4. Whats your production setup? Any load balancers, reverse proxies, application firewalls in place?
#3

[eluser]bretticus[/eluser]
[quote author="WanWizard" date="1282258118"]
4. Whats your production setup? Any load balancers, reverse proxies, application firewalls in place?[/quote]

Some load balancers will proxy the data (the load balancer becomes the web server point of demarcation.) In that case, the ip that you can grab via $_SERVER['REMOTE_ADDR'] (which is the mechanism sessions ultimately use) will come to your web server as the IP of the load balancer (the same everytime.) Often a load balancer will send some header to designate the real remote address. Try issuing a print_r($_SERVER) and see if you can find the real remote address. From there, you can use my extended Input class...

http://brettic.us/

(I would have linked it but I get a nice "black listed item found" error when I try to update this post. Huh??? Just look for the "PHP: Remote IP + Load Balancer" link as I can't even write that URL in the forum. Hmmm... I suppose my class could be used by a malicious hacker to mask his IP in a scenario where the load balancer DOES NOT use that header. Maybe I better put a disclaimer in. Still? blacklist it? You should never count on headers for anything secure anyway!)


...to look for that value first (and modify it for your needs depending on your output form printing the $_SERVER array.)

Make sure your AJAX calls have the same useragent as the browser. I noticed you have

Code:
$config['sess_match_useragent']    = TRUE;

In firefox the user agents are the same for ajax vs browser (I checked via firebug.) I dunno about other browsers.
#4

[eluser]fchristant[/eluser]
1. Yes, it is using Ajax calls, although the problem also appears on pages free of any Ajax calls. An interesting example is as follow...

javascript files in my project are not outside my CI project. I treat them as view to which I pass data. Odd, I know, but I have good reasons for this. Anyway, in my HTML header I of course load these js files. Let's say there are 3. Combined with the actual page itself, those are 4 requests coming into CI, all of the same IP and user agent. Guess what? I creates 4 sessions in the database.

In other words, Ajax is not the cause. Paralel requests seem to be the cause. The solution you indicate is therefore a solution for only a very specific case.

2. Thanks, I removed the underscore. It will not solve #1, but maybe it improves something else Smile

3. No issues as long as #1 is solved. Currently, an idnex job by Google creates x sessions times x pages, which means hundreds of new session entries in my db.

4. Hard to say, it is hosted at a leased server of which the lease plan is owned by an ex-coworker. I currently do not have the details of his setup. What is interesting though that I can capture the IP of a user in my custom CI code just fine using $this->input->ip_address();

Thanks for your time. It seems the root of most of my problems lies in #1. Other than switching to another session library completely, I have not found a solution yet. I would like to stay on CI's library as I do like the concept and I don't look forward to changing code much.
#5

[eluser]WanWizard[/eluser]
That is quite logical.

The browser doesn't have the session cookie until the page request is complete. And session cookies are only sent back to the server on page requests. If you request a CI resource in a link or img tag, no cookie will be sent to the server, so that's not going to work anyway.
If you really want to serve your assets through a CI call, than use separate controller that doesn't use or need sessions.

I'm pretty sure that another session library isn't going to solve it, as that's not where the issue is. The session library uses $this->input->ip_address() to fetch the IP address too. I think your method of serving assets is the culprit here.
#6

[eluser]bretticus[/eluser]
[quote author="WanWizard" date="1282262494"]
I'm pretty sure that another session library isn't going to solve it, as that's not where the issue is. The session library uses $this->input->ip_address() to fetch the IP address too. I think your method of serving assets is the culprit here.[/quote]

Yeah I suppose IP matching is off anyways.

Code:
$config['sess_match_ip']        = FALSE;

Odd, he's getting 0.0.0.0 in the database though on production. But another issue non-related to the immediate problem it would seem.
#7

[eluser]fchristant[/eluser]
Thank you, that makes sense.

I am now autoloading the session but I guess I could disable that and decide upon it in each controller's constructor? If so, for my CI JS files that would be easy since they all pass by my js.php controller.

As for Ajax calls, I now have them in various controllers. But I guess I could move them to a seperate controller as well as not load the session there.

Would that make sense?

I will first work on this and check if it works. I hope it solves the IP problem as well. As for users losing persistent sessions, I am not sure if this is related to issue #1 at all.

I have something to chew on now, thanks!
#8

[eluser]WanWizard[/eluser]
For Ajax calls, you might want to load the session and use the IS_AJAX trick to block the session_id from rotating, as you will probably have to fetch or store information that is related to a user or a security context.

To solve the controller issue, you could create two Controller extensions, MY_Controller (contains all stuff you need in 'normal' controllers), and MY_Asset_controller, for all your assets. Then have out js.php extend MY_Asset_controller instead of Controller, there others extend MY_Controller.
#9

[eluser]fchristant[/eluser]
A little update on my progress:

- I have moved the js files outside of my CI project. This alone got rid of a lot of session entries in the table

- There were still some mysterious duplicates appearing, seemingly random. It turns out my cron jobs (which use CI because they need the models) were causing this. I have now disabled the autoloading of the session class. All normal controllers extend my basecontroller which loads the session class, whilst my "services" controller, which is used for the cronjobs, extends the native Controller which does not load the session.

Although I am still testing, it looks like these two changes got rid of all duplicates, which is great. I have not yet applied the IS_AJAX trick. In my testing, my ajax calls do not seem to create duplicates. Maybe because they are user-invoked after the page is loaded?

I have not yet deployed this code to production because I have made other changes that I need to finish first, but I hope this solves the IP problem as well. Now that I think of it, I think it will, because I am figuring that it was the cronjob "sessions" which had an ip of 0.0.0.0, which makes sense, since they run on the same host.

All in all it looks like I succeeded in eradicating most if not all problems with your help. Thanks!
#10

[eluser]n0xie[/eluser]
[quote author="fchristant" date="1282319882"]
Although I am still testing, it looks like these two changes got rid of all duplicates, which is great. I have not yet applied the IS_AJAX trick. In my testing, my ajax calls do not seem to create duplicates. Maybe because they are user-invoked after the page is loaded?[/quote]
Read this: http://ellislab.com/forums/viewthread/138823/




Theme © iAndrew 2016 - Forum software by © MyBB