Зарегистрируйте пользователя в своем поддомене после регистрации с помощью Rails и Devise

Я использую Devise для аутентификации в моем приложении Rails 3. Приложение использует схемы PostgreSQL и жемчужину квартиры для облегчения многопользовательской аренды.

Вход и выход из определенного субдомена отлично работает после создания учетной записи. Пользователи могут только войти в субдомен для своей конкретной учетной записи, что отлично.

Здесь, где я сталкиваюсь с проблемами...

Новый пользователь попадает на URL регистрации:

http://foo.com/signup

По умолчанию, когда они нажимают кнопку "Отправить", создается новая учетная запись, но пользователь отправляется по адресу:

http://foo.com/dashboard

Вместо этого я хочу, чтобы они переходили к:

http://myaccount.foo.com/dashboard

Чтобы достичь этого, я перепробовал метод after_sign_up_path_for в моем файле registrations_controller.rb:

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

Но это позволяет любому войти в учетную запись на любом субдомене, что, очевидно, не круто.

Вопрос: Как я могу убедиться, что сеанс, созданный при регистрации, действителен для субдомена, созданного во время процесса регистрации

Ответы

Ответ 1

Вы можете использовать опцию domain: :all в вашем config.session_store и просто иметь 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

Ответ 2

Переопределите контроллер сеанса разработки.

Создайте файл с точным путем app/controllers/devise/sessions_controller.rb

Переопределить класс session_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

Я смотрю, могу ли я понять, как именно это сделать, но я точно знаю, что желаемый результат можно достичь, переопределив контроллер сеанса разработки.

ИЗМЕНИТЬ

Если вы используете куки-перекрестные субдомены, вы можете принудительно выполнить сеанс субдомена с помощью параметра before_filter. Например

before_action do 
    redirect_to root_path, alert: 'That subdomain does not belong to you' if request.subdomain != current_user.subdomain
end