Rails:重定向到规范域时如何保留会话(例如company.example.com - > example.com)

时间:2013-07-11 16:47:23

标签: ruby-on-rails-3 session redirect session-cookies

Rails 3.2.12,ruby 1.9.3

我们允许用户使用子域指定他们所在的公司,例如mycompany.example.com,但我们会重定向到规范example.com,并且需要记住该用户来自mycompany

我们已经设置了我们的环境,因此config.session_store包含:domain => 'example.com(也可以使用:domain => :all, :tld_length => 2),这应该可以在子域之间共享会话信息。有很多很棒的帖子,例如:Share session (cookies) between subdomains in Rails?

但在重定向之前,我将session.inspect发送到日志,并且显然正在获得不同的会话(两个单独的会话ID等)。因此,最基本的问题是,在我将其删除之前,我无法使用会话来记住mycompany部分。

我可以解决这个问题,但是在很多情况下,同一个用户来自多家公司(其中一部分是我们的支持团队,他们需要能够转换公司)。

我在OS X上的Chrome和Safari上试过这个。我正在使用“pow”,所以我的本地开发环境有一个像example.dev这样的域,可以帮助排除几个问题(与正常localhost:3000相比服务器)。

我错过了什么吗?是否确实可以跨域共享cookie?

更新:

ApplicationController中定义的before_filter中调用的示例代码:

def redirect_to_canonical_if_needed
  logger.debug "Starting before_filter. session contains: #{session}"
  if request.host != 'example.com'
    session[:original_domain] = "Originally came from #{request.host}"
    logger.debug "Redirecting, session contains: #{session}"
    redirect_to 'http://example.com', :status => :moved_permanently
  end
end

设置已添加到config/environments/production.rb并已从config/initializers/session_store.rb

中删除
  config.session_store = { :key => 'example_session', :secret => "secret", :domain => :all, :tld_length => 2 }

  config.session_store = { :key => 'example_session', :secret => "secret", :domain => 'example.com' }

并记录结果,如果我从没有会话的新环境开始,请访问网址a.example.com:

Starting before_filter, session contains: {}
Redirecting, session contains: {"session_id"=>"4de9b56fb540f7295cd3192cef07ba63", "original_domain"=>"a.example.com"}
Filter chain halted as :redirect_to_canonical_if_needed rendered or redirected
Completed 301 Moved Permanently in 2294ms (ActiveRecord: 855.7ms)
Started GET "/" for 123.456.789.123 at 2013-07-12 09:41:12 -0400
Processing by HomeController#index as HTML
  Parameters: {}
Starting before_filter, session contains: {}

因此,前置过滤器会触发每个新请求。首先请求没有会话,因此“未加载”消息。需要重定向的测试是真的。我在会话中添加了一些内容,它会获得一个id和我放入的内容。我做重定向。在过滤器再次触发之前,根域上发生了新请求,这就是问题:会话未初始化

1 个答案:

答案 0 :(得分:1)

这应该可以在我在dev

上设置以下两者之间正常工作

应用程序位于example.dev

我在a.example.dev中查看并设置了一个会话变量,然后访问b.example.dev,并且只要(如你所描述的那样)为会话存储设置域'example.dev'就设置它/ p>

我的根控制器/操作中的代码完全符合您的描述

unless request.subdomain.to_s == 'another'
  session[:original_domain] = request.subdomain.to_s
  redirect_to 'http://another.' + request.domain.to_s  
end

在会话中可以查看original_domain

如果您将示例代码放入其中,我可以查看任何陷阱