5

for some reason, the session handler in my RoR application seems to act weird in production for many users. I am using the default RoR ActiveRecord Session Store and in development everything works just fine. As long as I keep the browser open, one existing data row is being updated every time I modify the session, just like you'd expect sessions to work. When going to the production server, I personally observe the same behavior. However, when looking in the database, I see very many rows like on this screenshot:

http://imageshack.us/f/191/screenshot20110527at832.png/ (Sorry, but I cannot include images here directly since I am a new user)

The website is included in an iframe on another website and has a dispatcher, which will send (redirect_to) the user to another action in the same controller based on some session data, i.e. for all users, the same URL (mydomain.com/dispatcher) will be included in an iframe. The action mapped to this URL will then decide where to redirect the user to based based on session[:current_action].

The website barely has any traffic, so there is no way that there are actually approx. 10 distinct users making a request to the website every second. In fact, I can see in the production.log that while being redirected, the users have different session_ids, e.g. when visiting the dispatcher, the user may have a particular sessionid and when requesting the actual target action (as a consequence of the redirect_to in the dispatcher), the sessionid will have changed to something else. Furthermore, most (>= 97.5% of more than 16000 data rows) of the session data rows have a 'lifetime' of 0 seconds (i.e. created_at equals updated_at).

Do you have any idea what could cause this problem?

Is there any chance that redirect_to calls mess up the RoR session handling?

Thank you very much in advance for your thoughts!

jhuebner
  • 71
  • 1
  • 3
  • There might be something wrong with your database? That is a common issue, have you tried using the same type of database in development and does the issue persist then? – Devin M May 28 '11 at 04:06
  • what do your own cookies look like on production? maybe you have a wonky setting that is creating a new cookie for each subdirectory/resource? – John Bachir May 28 '11 at 04:22

3 Answers3

2

It's possible that your visitors are being issued new session_id values for each request because of some kind of configuration error, or a problem fetching the session from the database. With cookie-based sessions the common problem is the cookie is being assigned to the wrong domain, or you have conflict between the www.example.com and example.com host names when visiting the www version.

Another problem can be that the signature on the session is rejected and a new session is created automatically.

You may want to create a diagnostic page that simply dumps out the session.session_id for a particular user and then reload this to ensure that you're getting consistent results.

If you use Firebug, have a look at the headers to see if you're having the session re-assigned with each request, too.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • @Devin M: Thank you, but I don't think that's the issue. I am using mysql in both cases and the database settings look very similar in dev/prod. – jhuebner May 28 '11 at 04:57
  • @John Bachir: That's the strange part - I was not able to reproduce the problem myself, so far. I seem to be one of those lucky 2.5% of the users where that problem does not occur. For me, the session cookie (there is only one, since I am storing the session contents in the database) looks perfectly fine. That is true both for development and production. That's what the session cookie looks like: Name _myapp_session Value 73d4f19392a26e0599006756efc61727 Host localhost Path / Secure No Expires At End Of Session The value stays the same when navigating through the page. – jhuebner May 28 '11 at 05:04
  • I had a look at Firebug and through all the requests (i.e. all redirects) I had the same session_id. In the server log I also could not detect anything indicating a database read error (even for sessions of which I know they had a lifetime of 0 seconds). Your idea about the session rejection sounds very interesting, though. How do I best check that? Thanks a lot for your help! – jhuebner May 28 '11 at 05:17
  • You may have to dig a bit into Rails to find out what method is used to validate a session before using it. One thing to check is if this happens with cookie-based or memcached-based sessions, as it may be unique to database-backed ones. You can also tweak your web server to log the contents of the session cookies which may help with diagnostics. Apache allows the full customization of its logs, for instance, including the contents of cookies. – tadman May 28 '11 at 07:38
2

It turns out there were two problems:

  1. Third-Party cookies in Internet Explorer: Because the site was included in an iframe, all IEs (IE6-IE9) would block cookies including the session cookie. Following this, the user would be provided with a new session_id on every redirect.

  2. Furthermore, when switching between session storages in Rails (e.g. between Cookie and ActiveRecord Session Store), all existing sessions should be deleted/expired. Otherwise, RoR will generate huge session_ids, like in the following SQL statement:

    {:sql=>"INSERT INTO sessions (session_id, data, created_at, updated_at) VALUES ('BAh7CUkiD3Nlc3Npb25faWQGOgZFRiIlZmRhMzRjMzdiOWU0YjhhMzIyNGU0Y2IwOWZiN2E4YTJJIgptdHVyawY7AEZ7CToSYXNzaWdubWVudF9pZEkiIEFTU0lHTk1FTlRfSURfTk9UX0FWQUlMQUJMRQY7AFQ6C2hpdF9pZEkiIzJRRzhUTktJTVpTTVU4U1ZSR0ZNNVBHVjRNTFlCRQY7AFQ6Dndvcmtlcl9pZEkiE0ExQzdBNFFYUE5DOTRDBjsAVDoPc3VibWl0X3VybEkiGmh0dHBzOi8vd3d3Lm10dXJrLmNvbQY7AFRJIhVza2lwcGVkX3Rhc2tfaWRzBjsARlsGaQBJIhBfY3NyZl90b2tlbgY7AEZJIjFvbHJiK2tSaDZ1dDhyZ011VmUyZnZrY01wWWFuQll6cVY1YWZ4M0c1QkhFPQY7AEY=--a4223802cfb90e6c75578cc1a27427cf96778598', 'BAh7B0kiCm10dXJrBjoGRUZ7AEkiEmlzX2Rpc3BhdGNoZWQGOwBGVA==\n', '2011-05-28 05:47:19', '2011-05-28 05:47:19')

As a result, MySQL truncated the session-id to fit in the 255 chars (default column specification after the rails session migration). Consequently, on the following request, rails tried to recover the session using the (extremely long) session_id - of course without success.

I tried to fix the IE issue by adding the following HTTP Response header:

response.header["P3P"] = 'CP="CAO PSA CONi OTR OUR DEM ONL"'

However, that does not seem to work, which is why I am rewriting the app to work without any session information at all. Still, any further hints would be appreciated for future reference.

DarthJDG
  • 16,511
  • 11
  • 49
  • 56
jhuebner
  • 71
  • 1
  • 3
0

I'm using https://github.com/grosser/ie_iframe_cookies to handle this. It takes care of what jhuebner mentioned in addition to handling etags as noted here http://robanderson123.wordpress.com/2011/02/25/p3p-header-hell/

Nathan Hurst
  • 1,740
  • 14
  • 22