出于某种原因,我的RoR应用程序中的会话处理程序似乎在许多用户的生产中表现得很奇怪。我正在使用默认的RoR ActiveRecord会话存储,在开发过程中一切正常。只要我保持浏览器打开,每次修改会话时都会更新一个现有数据行,就像您希望会话一样。当我去生产服务器时,我个人观察到相同的行为。但是,在查看数据库时,我会在此屏幕截图中看到很多行:
http://imageshack.us/f/191/screenshot20110527at832.png/(抱歉,由于我是新用户,我无法直接在此处添加图片)
该网站包含在另一个网站上的iframe中,并且有一个调度程序,它将根据某些会话数据(即对所有用户,相同的URL)(mydomain)将用户发送(redirect_to)到同一控制器中的另一个操作。 com / dispatcher)将包含在iframe中。映射到此URL的操作将根据会话[:current_action]决定将用户重定向到哪里。
该网站几乎没有任何流量,所以实际上没有办法实现约。 10个不同的用户每秒向网站发出请求。事实上,我可以在production.log中看到在重定向时,用户有不同的session_id,例如当访问调度程序时,用户可能具有特定的sessionid,并且在请求实际目标操作时(由于调度程序中的redirect_to),sessionid将更改为其他内容。此外,会话数据行的大多数(>超过16000个数据行的97.5%)具有0秒的“生存期”(即created_at等于updated_at)。
你知道什么可能导致这个问题吗?
redirect_to调用是否有可能搞乱RoR会话处理?
非常感谢你的想法!
答案 0 :(得分:2)
事实证明存在两个问题:
Internet Explorer中的第三方Cookie:由于该网站包含在iframe中,因此所有IE(IE6-IE9)都会阻止包含会话cookie的Cookie。在此之后,将在每次重定向时向用户提供新的session_id。
此外,当在Rails中的会话存储之间切换时(例如,在Cookie和ActiveRecord会话存储之间),应删除/过期所有现有会话。否则,RoR将生成巨大的session_id,如以下SQL语句中所示:
{: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')
结果,MySQL截断了session-id
以适应255个字符(rails会话迁移后的默认列规范)。因此,在以下请求中,rails尝试使用(极长)session_id
恢复会话 - 当然没有成功。
我尝试通过添加以下HTTP响应标头来解决IE问题:
response.header["P3P"] = 'CP="CAO PSA CONi OTR OUR DEM ONL"'
然而,这似乎不起作用,这就是为什么我在没有任何会话信息的情况下重写应用程序。不过,任何进一步的提示都将受到赞赏以供将来参考。
答案 1 :(得分:1)
由于某种配置错误或从数据库中获取会话时出现问题,您的访问者可能会为每个请求发出新的session_id
值。对于基于cookie的会话,常见问题是cookie被分配到错误的域,或者在访问www.example.com
版本时,example.com
和www
主机名之间存在冲突。
另一个问题可能是会话上的签名被拒绝,并且会自动创建新会话。
您可能想要创建一个诊断页面,只是为特定用户转储session.session_id
,然后重新加载它以确保您获得一致的结果。
如果你使用Firebug,请查看标题,看看你是否也为每个请求重新分配了会话。
答案 2 :(得分:0)
我正在使用https://github.com/grosser/ie_iframe_cookies来处理这个问题。除了处理etags之外,它还会处理jhuebner提到的内容http://robanderson123.wordpress.com/2011/02/25/p3p-header-hell/