为什么 Ruby on Rails 在每次点击时(有时)都会创建新的会话?
由于某种原因,我的 RoR 应用程序中的会话处理程序对于许多用户来说在生产中似乎表现得很奇怪。我正在使用默认的 RoR ActiveRecord 会话存储,并且在开发过程中一切正常。只要我保持浏览器打开,每次修改会话时都会更新一个现有数据行,就像您期望会话正常工作一样。当进入生产服务器时,我个人观察到相同的行为。但是,在查看数据库时,我看到很多行,如以下屏幕截图所示:
http:// imageshack.us/f/191/screenshot20110527at832.png/(抱歉,但我不能直接在此处包含图像,因为我是新用户)
该网站包含在另一个网站的 iframe 中,并且有一个调度程序,它将根据某些会话数据将用户发送(redirect_to)到同一控制器中的另一个操作,即对于所有用户,相同的 URL (mydomain.com/dispatcher) 将包含在 iframe 中。映射到此 URL 的操作将根据 session[:current_action] 决定将用户重定向到哪里。
该网站几乎没有任何流量,因此不可能实际有大约。每秒有 10 个不同的用户向网站发出请求。事实上,我可以在 production.log 中看到,在被重定向时,用户具有不同的 session_id,例如,在访问调度程序时,用户可能具有特定的 sessionid,并且在请求实际目标操作时(由于调度程序中的redirect_to,sessionid 将更改为其他内容。此外,大多数(≥16000个数据行中的97.5%)会话数据行具有0秒的“生命周期”(即created_at等于updated_at)。
您知道什么可能导致此问题吗?
redirect_to 调用是否有可能扰乱 RoR 会话处理?
预先非常感谢您的想法!
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于某种配置错误或从数据库获取会话时出现问题,您的访问者可能会为每个请求发出新的
session_id
值。对于基于 cookie 的会话,常见问题是 cookie 被分配给错误的域,或者www.example.com
和example.com
主机名之间存在冲突访问www
版本时。另一个问题可能是会话上的签名被拒绝并自动创建新会话。
您可能想要创建一个诊断页面,仅转储特定用户的
session.session_id
,然后重新加载该页面以确保获得一致的结果。如果您使用 Firebug,请查看标头,看看是否也为每个请求重新分配了会话。
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 thewww.example.com
andexample.com
host names when visiting thewww
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.
事实证明,存在两个问题:
Internet Explorer 中的第三方 cookie:由于该站点包含在 iframe 中,因此所有 IE (IE6-IE9) 都会阻止包括会话 cookie 在内的 cookie。此后,每次重定向时都会向用户提供新的 session_id。
此外,当在 Rails 中的会话存储之间切换时(例如在 Cookie 和 ActiveRecord 会话存储之间),所有现有会话都应被删除/过期。否则,RoR将生成巨大的session_ids,如以下SQL语句:
<块引用>
{:sql=>"INSERT INTO
sessions
(session_id
,data
,created_at
,updated_at
) 值('BAh7CUkiD3Nlc3Npb25faWQGOgZFRiIlZmRhMzRjMzdiOWU0YjhhMzIyNGU0Y2IwOWZiN2E4YTJJIgptdHVyawY7AEZ7CToSYXNzaWdubWVudF9pZEkiIEFT U0lHTk1FTlRfSURfTk9UX0FWQUlMQUJMRQY7AFQ6C2hpdF9pZEkiIzJRRzhUTktJTVpTTVU4U1ZSR0ZNNVBHVjRNTFlCRQY7AFQ6Dndvcmtlcl9pZEkiE0ExQzd BNFFYUE5DOTRDBjsAVDoPc3VibWl0X3VybEkiGmh0dHBzOi8vd3d3Lm10dXJrLmNvbQY7AFRJIhVza2lwcGVkX3Rhc2tfaWRzBjsARlsGaQBJIhBfY3NyZl90b 2tlbgY7AEZJIjFvbHJiK2tSaDZ1dDhyZ011VmUyZnZrY01wWWFuQll6cVY1YWZ4M0c1QkhFPQY7AEY=--a4223802cfb90e6c75578cc1a27427cf96778598', 'BAh7B0kiCm10dXJrBjoGRUZ7AEkiEmlzX2Rpc3BhdGNoZWQGOwBGVA==\n', '2011-05-28 05:47:19', '2011-05-28 05:47:19')此外
结果,MySQL 截断了
session-id
适应255 个字符(rails 会话迁移后的默认列规范)因此,根据以下请求,rails 尝试使用(极长的)session_id
恢复会话 - 当然没有成功。我尝试通过添加以下 HTTP 响应标头来修复 IE 问题:
但是,这似乎不起作用,这就是为什么我重写应用程序以在没有任何会话信息的情况下工作。尽管如此,任何进一步的提示将不胜感激,以供将来参考。
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:
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:
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.
我正在使用 https://github.com/grosser/ie_iframe_cookies 来处理此问题。除了处理 etag 之外,它还负责 jhuebner 提到的内容 http ://robanderson123.wordpress.com/2011/02/25/p3p-header-hell/
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/