Why does Ruby on Rails create new Sessions on every hit (sometimes)?
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. 开发者_Go百科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!
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.
It turns out there were two problems:
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.
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.
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/
精彩评论