Ray*_*ski 5 ruby ruby-on-rails devise apartment-gem
我已经在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)
Run Code Online (Sandbox Code Playgroud)
我也尝试过以下方法:
Rails.application.config.session_store :cookie_store, key: '_myapp_session', domain: :all
Run Code Online (Sandbox Code Playgroud)
我需要做什么才能从任何子域登录?
测试案例将是:
用户user1访问网址app.myapp.com/users/sign_in提供其凭据,因此登录并重定向到user1.myapp.com.
奖励:user1访问网址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
Run Code Online (Sandbox Code Playgroud)
和
# /app/classes/excluded_subdomains.rb
class ExcludedSubdomains
def self.subdomains
%w( www admin test public private staging app web net )
end # subdomains
end # class
Run Code Online (Sandbox Code Playgroud)
和
# /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
Run Code Online (Sandbox Code Playgroud)
和
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
Run Code Online (Sandbox Code Playgroud)
Ray*_*ski 10
我发现了问题!而不是使用域预先添加应用程序域.app应该没有前面的子域,而是一个点.像这样:
# /config/initializers/session_store.rb
Rails.application.config.session_store :cookie_store, key: '_myapp_session', domain: {
production: '.myapp.com',
staging: '.myapp.com',
development: '.lvh.me'
}.fetch(Rails.env.to_sym, :all)
Run Code Online (Sandbox Code Playgroud)
我很难找到这个简单的错误,甚至我创建了一个示例应用程序.由于这个例子已经存在,我想我可以分享它.它可以在GitHub找到.
| 归档时间: |
|
| 查看次数: |
2554 次 |
| 最近记录: |