Rails 4多租户子域登录管理

4
场景:多租户Rails应用程序,使用子域和devise 问题:我希望用户能够登录到mydomain.com,然后作为已登录用户被转发到他们自己的子域1.mydomain.com地址。现在他们只能直接登录到自己的子域。 我是一个相对新手的Rails开发者,我找不到简单的解决方案(尽管似乎必须有一个)。理想情况下,我希望mydomain.com和subdomain1.mydomain.com共享一个cookie,但我没有编写自定义中间件的技能。显然,由于它是多租户,我不能在所有子域之间共享一个会话。我困在这里几天了,好奇是否有一个简单的解决方案(例如config.session_store domain设置),我错过了什么,然后再开始看OAuth或其他更繁琐的解决方案。任何帮助都将不胜感激! 编辑:当然,在发布后我才发现这个Log a user into their subdomain after registration with Rails and Devise 。将尝试使用配置session_store domain:all和before filter建议,并在不起作用时发布任何详细信息,至少看起来像个好主意。

编辑:适用于我的特定带有子域名设置的Devise的解决方案:

class ApplicationController < ActionController::Base

  before_action :check_subdomain

  def check_subdomain 
    unless request.subdomain == "" or request.subdomain == session[:subdomain]
      redirect_to request.protocol+request.domain
    end
  end

end

session_store.rb
My::Application.config.session_store :cookie_store, key: '_my_session' , :domain => :all, :tld_length => 2

基本上,我在登录时使用session[:subdomain]设置子域,并使用它来将会话限定为当前用户。否则,当session_store中的域设置为:all时,它会破坏范围。如果用户未经授权,则通过request.protocol(http://或https://)+ request.domain重定向到公共主页。简单!现在用户可以在同一会话中在基础域和子域之间移动。
1个回答

2

Cookie

从您发布的信息来看,我估计您在跟踪会话cookie方面遇到了问题。我们的子域应用程序也出现了类似的问题,导致每次在两个之间切换时都会删除cookie。

我们在这里找到了解决方法: 在Rails中共享会话(cookie)子域之间的内容?

#config/initializers/session_store.rb
Your_App::Application.config.session_store :cookie_store, key: '_your_app_session', domain: :all, tld_length: 2

这个技巧在于tld_length参数 - 这允许您定义可以容纳多少个“级别”的域名;例如,如果您正在使用子域,则需要设置tld_length以反映它。


转发

我不确定您是否有关于转发的问题;无论如何,我会给您一些想法。

当您登录到“子域”时,除非您有真正的Rails多租户实现(每个用户存储在不同的数据库中),否则您应该能够允许用户在主表单上登录,然后将其重定向到子域而不会出现问题。

您需要考虑的是,subdomain约束仅在使用_url路径助手时才会被填充

<%= link_to "Your Name", path_url(subdomain: "subdomain_1") %>

这是因为_path助手相对于基本URL,因此无法填充subdomain选项。相反,_url路径助手指向整个URL - 允许您根据需要定义子域。
--
如果您发送请求并继续希望用户保持登录状态,则需要确保能够在子域之间保持身份验证。例如,如果您在“主”页面上有一个单一登录表单,则需要确保可以将身份验证继续到子域中。

谢谢Rich,我目前没有使用domain: :all,所以如果尝试将auth从基础域移动到子域,则会遇到无效的真实性令牌。明天我打算尝试使用domain: :all,tld_length: 2和before过滤器,看看是否可以让我运行起来。 - mrc
before_filter 有什么用途? - Richard Peck
为了保持作用域,因为我将在所有子域中拥有单个会话。编辑:子域而不是。 - mrc
数据库调用的范围? - Richard Peck
1
在纸面上,这个解决方案非常符合我的情况。我们拭目以待! - mrc
不错!我已经为被接受的答案点赞了,所以我之前一定看过这个问题 :D - Richard Peck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接