5

Apartment (1.2.0) とDevise (4.2.0)で Rails 5 アプリケーションをセットアップしました。いくつかの DDNS の問題により、アプリにのみアクセスできるという制約がありますapp.myapp.com(サブドメインに注意してくださいapp)。myapp.comにリダイレクトしapp.myapp.comます。

私の使用例は、アプリにサインアップしたすべてのユーザー (テナント) が、サブドメイン (例: tenant.myapp.com) を介して特定のデータにアクセスする必要があるというものです。ユーザーのスコープをサブドメインに限定しないでください。基本的にどのサブドメインからでもサインインできるはずです。テナントの正しいサブドメインへのリダイレクトは、によって処理されApplicationControllerます。Devise の標準に従って、ログイン ページは にありますapp.myapp.com/users/sign_in。ここから問題が始まります。

「メールアドレスまたはパスワードが正しくありません」エラーのため、ユーザーはログインできません。

開発中、ちょっと遊んでみました。からのサインインはlvh.me完全にうまく機能します。ユーザーがログインし、サブドメインにリダイレクトされます。で同じことをapp.lvh.me試みると、前述の問題が発生します。

セッション ストアを次のように設定しました。

# /config/initializers/session_store.rb
Rails.application.config.session_store :cookie_store, key: '_myapp_session', domain: {
  production:   '.app.myapp.com',
  staging:      '.app.myapp.com',
  development:  '.app.lvh.me'
}.fetch(Rails.env.to_sym, :all)

また、次のことも試しましたが、どちらも機能しません。

Rails.application.config.session_store :cookie_store, key: '_myapp_session', domain: :all

どのサブドメインからでもログインできるようにするには、どうすればよいですか?

テスト ケースは次のようになります。

ユーザーは資格情報を提供user1する URL にアクセスapp.myapp.com/users/sign_inし、そのためサインインして にリダイレクトされuser1.myapp.comます。

おまけ: user1URL にアクセスanother_user.myapp.com/users/sign_inすると資格情報が提供されるため、サインインして にリダイレクトされuser1.myapp.comます。

編集

その他の関連する構成:

# /config/initializers/apartment.rb
config.excluded_models = %w{ User }
config.tenant_names = lambda { User.pluck :subdomain }
config.tld_length = 2
Rails.application.config.middleware.insert_before Warden::Manager, Apartment::Elevators::FirstSubdomain
Apartment::Elevators::FirstSubdomain.excluded_subdomains = ExcludedSubdomains.subdomains

# /app/classes/excluded_subdomains.rb
class ExcludedSubdomains
  def self.subdomains
    %w( www admin test public private staging app web net )
  end # subdomains
end # class

# /app/models/user.rb
class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :confirmable, :lockable

  after_create :create_tenant
  after_destroy :delete_tenant

  # other stuff
  def create_tenant
    Apartment::Tenant.create(subdomain)
  end # create_tenant


  def delete_tenant
    Apartment::Tenant.drop(subdomain)
  end # delete_tenant
end # class

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  before_action :authenticate_user!
  before_action :redirect_to_subdomain

  private
  def redirect_to_subdomain
    return if self.is_a?(DeviseController) || self.is_a?(Users::OnboardingController)

    if current_user.present? && request.subdomain != current_user.subdomain
      redirect_to main_index_url(subdomain: current_user.subdomain)
    end # if
  end # redirect_to_subdomain

  def after_sign_in_path_for(resource_or_scope)
    users_onboarding_start_url(subdomain: resource_or_scope.subdomain)
  end # after_sign_in_path_for

  def after_sign_out_path_for(resource_or_scope)
    successful_logout_url(subdomain: '')
  end # after_sign_out_path_for
end # class
4

2 に答える 2