Rails 4应用程序中的子域名

今天我遇到了一个相当奇怪的现象。 在开发一个Rails应用程序时,每个用户都有自己的子域,并尝试使用Devise来完成它,我遇到了也没有注册任何路由到根页面的子域。 因此,例如,即使没有(显式)子域,它也会将我路由到主应用程序页面。 也许这与我的特定设置有关? 我也尝试了一个新的Rails项目,但我得到了相同的结果。 有人能为我澄清一下吗? Railscasts没有做到这一点。

此外,现在我正在使用WEBrick,即使这不是我将在生产中使用的,我正在使用域lvh.me来访问子域。

谢谢您的帮助。

编辑:这是我的routes.rb文件:

Rails.application.routes.draw do devise_for :users root 'static_page#index' end 

我遵循Devise wiki的这个指南: https : //github.com/plataformatec/devise/wiki/How-to :-Scope-login-to-subdomain

所以我做的是通过迁移删除了电子邮件的唯一性,然后我添加了:子域到request_keys,如下所示:

 devise :database_authenticatable, :recoverable, :rememberable, :trackable, :timeoutable, request_keys: [:subdomain] 

然后我继续覆盖“find_for_authentication”函数,如下所示:

 def self.find_for_authentication(conditions={}) conditions[:account_id] = Account.find_by_subdomain(conditions.delete(:subdomain)).id super(conditions) end 

这就是总结它。

编辑:我一直在搞乱,我发现了问题。 ‘root’指令将所有子域引用到我的域。 因此,如果我从routes.rb中删除root,则每个子域都会导致RouteError。 我记得在我的应用程序中为Devise需要一个root。 所以我不确定这是Devise的行为还是root。

你可能有几个问题

首先,您需要了解Devise在登录后重定向您的用户的方式,其次是如何在Rails中路由子域。

设计

默认情况下,将路由设置为current_user_path (通常表示users#show #show )或路由中的某些内容:

 def after_sign_in_path_for(resource) current_user_path end 

这意味着当您接受用户的登录时,他们将被带到他们自己的路径。 根据您的路线,这通常表示主站点(无子域)用户的路径( domain.com/users/56 )或其他内容。

从你的问题中没有任何具体细节,我只能推测这一点。

子域

刚刚开发了一些支持子域的应用程序,您应该考虑将其路由到子域。

用户登录后,需要将其路由到特定的subdomain 。 这样做的方法是在路由中使用constraint

 #config/routes.rb constraints { subdomain: 'admin' } do resources :photos end 

我们发现你不能使用普通的路由路径 – 你必须使用url (不是path助手)。 例如:

 photos_path(subdomain: current_user.name) #-> does not work (path is relative) photos_url(subdomain: current_user.name) #-> will route to http://name.lvh.me:3000 

您需要记住的是,如果您要将流量重定向/路由到不同的子域,则需要引用帮助程序的urlforms,而不是path引用。

因此,如果您按照上面所示采用after_sign_in_path_for ,您将需要执行以下操作:

 def after_sign_in_path_for(resource) root_url(subdomain: resource.name) end 

会议

最后,您希望确保您的Devise会话cookie在设置后仍保持初始化状态。 我们发现默认情况下不会处理子域名,因此您必须确保他们能够满足以下条件:

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

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

我手动解决了。 我发现routes.rb中的’root’指令接受来自每个子域的请求。 最后,我实现了一个自定义约束,并将其添加到routes.rb文件中devise_for的约束中。 这充分解决了我的问题。 感谢大家的帮助!

更新:

在回复询问我的代码的评论时:我们设置了一个系统,每个帐户(企业帐户)都有自己的子域名,每个企业帐户都有很多用户。 我的子域约束看起来像

LIB / subdomain.rb

 class Subdomain def self.matches?(request) request.subdomain.present? && Account.exists?(subdomain: request.subdomain) end end 

然后在我的config / routes.rb中,我使用该约束来路由请求:

配置/ routes.rb中

 require 'Subdomain' Rails.application.routes.draw do # Some routes... constraints(Subdomain) do devise_for :users, controllers: {:sessions => 'session'} root 'dashboard#index' # More subdomain constrained routes... end end 

在我原来的问题中,我发布了我已经展示了其余的设置。 我希望这可以帮助别人。