在使用Rails和Devise注册后,将用户登录到其子域
我在我的Rails 3应用程序中使用Devise进行身份validation。 该应用程序使用PostgreSQL模式和Apartment gem来促进多租户。
创建帐户后 ,登录和退出特定子域的工作正常。 用户只能在子域上登录其特定帐户,这很棒。
这是我遇到问题的地方……
全新用户点击注册url:
http://foo.com/signup
默认情况下,当他们单击“提交”时,将创建新帐户,但会将用户发送到:
http://foo.com/dashboard
相反,我希望他们去:
http://myaccount.foo.com/dashboard
为了实现这一点,我覆盖了registrations_controller.rb
文件中的after_sign_up_path_for
方法:
def after_sign_up_path_for(resource) root_url(:subdomain => resource.account.subdomain) end
这按预期工作 – 它加载正确的URL – 但用户的会话是为根域(foo.com)而不是子域创建的,因此要求用户登录。
我发现的一个建议是将config/initializers/session_store.rb
更改为:
config.session_store :cookie_store, :key => '_domain_session', :domain => :all
但这允许任何人登录任何子域的帐户,这显然不是很酷。
问题:如何确保注册时创建的会话对注册过程中创建的子域有效
您可以在config.session_store中使用domain: :all
选项,只需按照注释中某些人的建议使用before_action。
所以你仍然会在config / initializers / session_store.rb或config / application.rb中获得代码:
config.session_store :cookie_store, :key => '_domain_session', :domain => :all
然后在application_controller中添加以下代码:
#app/controllers/application_controller.rb before_action :check_subdomain def check_subdomain unless request.subdomain == current_user.account.subdomain redirect_to root_path, alert: "You are not authorized to access that subdomain." end end
覆盖设计会话控制器。
使用确切路径 app/controllers/devise/sessions_controller.rb
创建一个文件
覆盖该控制器中的sessions_controller类。 粘贴在链接中找到的代码中。 https://github.com/plataformatec/devise/blob/master/app/controllers/devise/sessions_controller.rb
class Devise::SessionsController < DeviseController # copy-paste the devise session controller below. ... end
编辑create
操作以满足您的需求。
def create self.resource = warden.authenticate!(auth_options) set_flash_message(:notice, :signed_in) if is_flashing_format? sign_in(resource_name, resource) yield resource if block_given? respond_with resource, :location => after_sign_in_path_for(resource) end
我想知道我是否能弄清楚如何完成这项工作,但我确信你想要的结果可以通过覆盖设计会话控制器来实现。
编辑
如果您使用的是跨子域Cookie,则可以使用before_filter强制执行子域会话。 例如
before_action do redirect_to root_path, alert: 'That subdomain does not belong to you' if request.subdomain != current_user.subdomain end