跨子域访问会话(Rails 4)

Posted

技术标签:

【中文标题】跨子域访问会话(Rails 4)【英文标题】:Access session across subdomains (Rails 4) 【发布时间】:2013-10-11 16:18:05 【问题描述】:

您好,我有一个多租户 rails 4 应用程序,它有一个简单的登录解决方案。但是,每个用户都有一个用户在登录后被重定向到的子域。

问题是当他们到达子域时,由于会话不跨子域共享的已知问题,他们不再登录。

我已经尝试了几种不同的解决方案来解决这个问题,但是我没有让会话跨子域持续存在。我认为这可能与我的开发环境有关?

我已经尝试了这个问题的所有答案: Share session (cookies) between subdomains in Rails?

似乎没有任何效果。我在这里缺少什么吗?是浏览器还是 rails 4 或....?我应该如何解决这个问题?

编辑: 我的 session_store 初始化器:

Imagesite::Application.config.session_store :cookie_store, key: '_imagesite_session', :domain => "imagesite.dev"

我也试过".imagesite.dev":all

我还尝试了 Evan 在上面链接的另一个问题中描述的解决方案。

子域示例:“ole.imagesite.dev”或“ole2.imagesite.dev”只是基于用户作为其子域输入的基本子域。

【问题讨论】:

你的开发环境是什么样的?你在使用 pow.cx 吗?您是否尝试过删除浏览器的 cookie? 嗨,是的,我正在使用 pow.cx 并且我试图删除 cookie。但我也尝试过启动服务器并使用 lvh.me:3000 访问它。 【参考方案1】:

我终于解决了!

我必须在创建 auth_token cookie 时设置域。像这样:

cookies[:auth_token] =  value: user.auth_token, domain: ".lvh.me" 

然后像这样删除cookie:

cookies.delete(:auth_token, :domain => '.lvh.me')

完整示例:

  def create
    user = User.find_by_username(params[:username])
    user ||= User.find_by_email(params[:username])
    if user && user.authenticate(params[:password])
      # session[:user_id] = user.id
        if params[:remember_me]
        cookies.permanent[:auth_token] =  value: user.auth_token, domain: ".lvh.me" 
      else
        cookies[:auth_token] =  value: user.auth_token, domain: ".lvh.me" 
      end
        redirect_to root_url(:subdomain => "#current_user.subdomain"), notice: "You are now loged in."
    else
        flash.now.alert = "Email or password is invalid"
        render "new"
    end
  end

  def destroy
    #session[:user_id] = nil
    cookies.delete(:auth_token, :domain => '.lvh.me')
    redirect_to root_url(:subdomain => false), notice: "Loged out"
  end

【讨论】:

【参考方案2】:

使用 Rails 4.2.5.1,以下对我有用:

Rails.application.config.session_store :cookie_store, key: '_magic_session', tld_length: 2

是的,没有 domain: 选项。

更新:最好将domain: 选项设置为:all

Rails.application.config.session_store :cookie_store, key: '_magic_session', domain: :all, tld_length: 2

如果env["HTTP_HOST"] 在开发环境中或在代理后面持有IP 地址而不是域名,则它可能必须是domain: "magic.com"。对于nginxproxy_set_header HOST $host:$server_port;可以保留域名。

【讨论】:

@xiaopang,这也是我的愿望。我试图不对它进行硬编码,但是在仅域和子域的某种组合中,没有检索到会话。那是在清除浏览器的 cookie 之后。 是的,似乎不可能,我只是添加了环境检查开发/生产来设置不同的会话存储。 @xiaopang:查看我编辑的更新......我们的愿望已经实现:)。无需设置不同的会话存储。 它有效,但如果主域名是 sub.domain.co.uk,我想我需要将tld_length: 2 设置为tld_length: 3?谢谢! 我自己没有测试过,但我很确定应该是这样。【参考方案3】:

在会话初始化程序中手动设置域一直对我有用。你可以发布你的初始化程序吗?还有一些您尝试在其间移动的子域的示例?

【讨论】:

你每次更改初始化器后都重新启动服务器? 是的。在我的 pow 服务器上使用“touch tmp/restart.txt”。 但是,测试我是否可以访问会话的最佳方法是什么?现在我只是尝试获取“current_user”。 您是否在为“imagesite.dev”设置 cookie,然后通过 lvh.me 访问它? (imagesite.dev 没有为我解决任何问题...) imagesite 是我的项目名称。我正在使用 pow 服务器,因此当您设置它时,pow 服务器地址将成为服务器名称加上“.dev”。因此“imagesite.dev”。我可以使用普通服务器并访问 lvh.me,但到目前为止它还没有工作。

以上是关于跨子域访问会话(Rails 4)的主要内容,如果未能解决你的问题,请参考以下文章

跨子域的Cookie

跨域 cookie 访问(或会话)

ruby 在开发模式下访问子域。 Rails 3

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

Express 中跨子域的会话

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