Zaloguj użytkownika do swojej subdomeny po rejestracji w Rails i Devise

Używam Devise do uwierzytelniania w mojej aplikacji Rails 3. Aplikacja wykorzystuje Schematy PostgreSQL i Gem mieszkania w celu ułatwienia wielu najmu.

Logowanie i wychodzenie z konkretnej subdomeny działa świetnie Po utworzeniu konta. Użytkownicy mogą logować się tylko na subdomenie dla swojego konkretnego konta, co jest świetne.

Oto, gdzie mam problemy...

Nowy użytkownik trafia na adres URL rejestracji:

http://foo.com/signup

Domyślnie, po kliknięciu przycisku Wyślij nowe konto zostanie utworzone, ale użytkownik zostanie wysłany na adres:

http://foo.com/dashboard

Zamiast tego chcę, aby poszli do:

http://myaccount.foo.com/dashboard

Aby to osiągnąć, przeredagowałem metodę after_sign_up_path_for w moim pliku registrations_controller.rb:

def after_sign_up_path_for(resource)
  root_url(:subdomain => resource.account.subdomain)
end

To działa zgodnie z przeznaczeniem -- ładuje poprawny adres URL -- ale sesja użytkownika została utworzona dla domeny głównej (foo.com) zamiast subdomeny, więc użytkownik jest proszony o zalogowanie się.

Jedna sugestia, którą znalazłem, to zmiana config/initializers/session_store.rb do:

config.session_store :cookie_store, :key => '_domain_session', :domain => :all

Ale To pozwala każdemu zalogować się do konta na dowolnej subdomenie, co oczywiście nie jest fajne.

Pytanie: Jak mogę upewnić się, że sesja utworzona podczas rejestracji jest ważna dla subdomeny, która została utworzona podczas procesu rejestracji

Author: Rob Sobers, 2013-12-11

2 answers

Możesz użyć opcji domain: :all w swoim config.session_store i po prostu mieć before_action tak jak sugerują niektórzy w komentarzach.

Więc nadal będziesz miał kod w config/initializers / session_store.rb lub w config/aplikacji.rb:

config.session_store :cookie_store, :key => '_domain_session', :domain => :all

Następnie w application_controller Dodaj następujący kod:

#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
 21
Author: Gjaldon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-15 16:59:02

Nadpisuje kontroler sesji devise.

Utwórz plik z dokładną ścieżką app/controllers/devise/sessions_controller.rb

Nadpisuje klasę sessions_controller w tym kontrolerze. Wklej kod znajdujący się pod linkiem. 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

Edytuj działanie create w zależności od twoich potrzeb.

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

Zastanawiam się, czy uda mi się wymyślić, jak to zrobić, ale wiem na pewno, że pożądany wynik jest osiągalny przez nadpisanie kontrolera sesji devise.

EDIT

Jeśli używasz plików cookie między subdomenami, możesz wymusić sesję subdomeny za pomocą before_filter. Na przykład

before_action do 
    redirect_to root_path, alert: 'That subdomain does not belong to you' if request.subdomain != current_user.subdomain
end
 1
Author: OneChillDude,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-20 02:38:46