使用子域在 Rails 2.3.2 应用程序中丢失会话

Posted

技术标签:

【中文标题】使用子域在 Rails 2.3.2 应用程序中丢失会话【英文标题】:Losing session in rails 2.3.2 app using subdomain 【发布时间】:2010-10-14 09:57:42 【问题描述】:

我有一个 2.2.3 的应用,我升级到了 2.3.2

这是一个多站点(使用子域),可为所有站点创建一个***会话。

这就是我在 production.rb 中更改域的方式:

ActionController::Base.session_options[:domain] = "example.com"

# in rails 2.2.2, this is what i used to do:
# ActionController::Base.session_options[:session_domain] = "example.com" 

我升级后开始发生奇怪的事情 我无法再使用 RESTful 身份验证登录;它确实对我进行了身份验证,但一旦我被重定向,它就会要求我再次登录。

正如我所说,我使用restful_authentication,我也使用passenger 2.1.2。 有人可以帮忙吗?

【问题讨论】:

弗拉德的回答正确吗? 【参考方案1】:

Olly 的回答是正确的,在 rails 2.3 中应该是:

config.action_controller.session[:domain] = '.example.com'

我只是想补充一点,如果您还没有创建一些会话选项,您可能会在使用它时收到这个:

undefined method `[]=' for nil:NilClass

在这种情况下,您应该改用它(创建会话变量而不是更新它):

config.action_controller.session ||= 
config.action_controller.session[:domain] = '.example.com'

编辑:显然 Rails 2.2.2 项目使用了不同的东西。 "domain" 应命名为 "session_domain" 并去掉域前面的句点字符。试试这个:

config.action_controller.session ||= 
config.action_controller.session[:session_domain] = 'example.com'

【讨论】:

这对我设置安全会话很有帮助。【参考方案2】:

在 Rails 2.3 中你应该使用

config.action_controller.session[:domain] = '.example.com'

【讨论】:

我尝试将其放入 development.rb 并得到:undefined method `[]=' for nil:NilClass 啊!弄清楚了。会话变量尚未创建。这有效:config.action_controller.session = :domain => '.example.com'【参考方案3】:

更安全的解决方案是检查会话是否已经存在。如果您盲目地替换整个会话对象,它可能会在未来绊倒您。

if ActionController::Base.session
  ActionController::Base.session[:domain] = '.example.com'
else
  ActionController::Base.session =  :domain => '.example.com' 
end

我喜欢在初始化文件中这样做。

【讨论】:

【参考方案4】:

只是想提一下,另一种为 cookie 处理整个子域的方法是动态的。适用于 2.3.4。

环境中有这样的东西.rb

# solution to use the cookies in the api. domains
# this is relevant but in 2.3.4 the code is different
# http://szeryf.wordpress.com/2008/01/21/cookie-handling-in-multi-domain-applications-in-ruby-on-rails/
# Just making sure that api. shares the domain name
require 'dispatcher'
module ActionController
  class Dispatcher
    def set_session_domain
      host_name = @env['SERVER_NAME']
      new_host_name = whatever #some mod of the host_name, for instance
      ActionController::Base.session = 
        :domain => new_host_name
      
    end

    before_dispatch :set_session_domain
  end
end

【讨论】:

【参考方案5】:

我正在运行 Rails 2.3.5 并且有

config.action_controller.session = :domain => '.localhost:3000'

在我的 development.rb 中,但我没有让它工作?

还有什么需要做的吗?

【讨论】:

【参考方案6】:

您必须说明:

.example.com

(注意前导点)以便会话cookie应用于example.com 及其子域

【讨论】:

【参考方案7】:

我们遇到了同样的问题(丢失会话,没有子域),使用 nginx + Thin。迁移到 apache + Passenger(最新版本)解决了这个问题。

【讨论】:

【参考方案8】:

我也在运行 2.3.5 并遇到与 @alfred-nerstu 类似的问题

@schickm 的补丁没有错误消息,但似乎也不需要。

【讨论】:

【参考方案9】:

它可以添加到您设置会话密钥和秘密的同一位置

config.action_controller.session = 
      :key => '_app_session',
      :domain => '.domain.com',
      :secret => 'secret'

【讨论】:

【参考方案10】:

我在使用基于 cookie 的会话时遇到了同样的问题。升级到 Passenger 2.1.3 似乎解决了这个问题。

【讨论】:

以上是关于使用子域在 Rails 2.3.2 应用程序中丢失会话的主要内容,如果未能解决你的问题,请参考以下文章

rails: 如何基于子域覆盖locale?

本地主机上的 rails 子域

在 Rails 中的子域之间共享会话(cookie)?

子域和本地安装的 Rails 应用程序

Rails 4 服务器/VueJS 开发服务器和子域的 Nginx 反向代理

跨子域访问会话(Rails 4)