我的身份验证需要独立:
subdomain1.domain.com subdomain2.domain.com 等
现在使用设计user_signed_in?
帮助程序 - 如果有人在subdomain1上进行身份验证,则它正在使用subdomain2。我想添加一个tenant_id范围来防止这种情况发生。
我已经能够在我的模型中使用以下命令执行此操作:
def self.find_for_database_authentication(warden_conditions)
where(:email => warden_conditions[:email], :tenant_id => warden_conditions[:tenant_id]).first
end
但我不知道如何在登录检查中执行此操作。
谢谢!
答案 0 :(得分:4)
为了做到这一点,您需要将身份验证的范围缩小到仅限于子域。
以下是有关如何完成此操作的Docs页面。我将在此处添加以供参考:
<强>概述强>
:subdomain
find_for_authentication
修改迁移
首先,您必须删除电子邮件索引唯一性约束。因为我们将把它转换为范围查询,所以我们将新索引的范围限定为子域。如果这是一个全新的Devise模型,您可以打开Devise迁移并更改以下内容:
# db/migrate/XXX_devise_create_users.rb
def change
# Remove this line
add_index :users, :email, :unique => true
# Replace with
add_index :users, [:email, :subdomain], :unique => true
end
如果这是一个现有项目,您需要创建一个新的迁移,删除旧索引并添加一个新索引:
rails g migration reindex_users_by_email_and_subdomain
# db/migrate/XXX_reindex_users_by_email_and_subdomain.rb
def change
remove_index :users, :email
add_index :users, [:email, :subdomain], :unique => true
end
更改登录密钥
在您的Devise模型中,将:subdomain
添加到:request_keys
。默认情况下,:request_keys
设置为[]
。
# app/models/user.rb
class User
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, request_keys: [:subdomain]
end
如果你有多个Devise模型,并且你希望它们都具有相同的:request_keys配置,你可以在config / initializers / devise.rb中全局设置
config.request_keys = [:subdomain] # default value = []
如果您还希望仍然能够使用不带子域的URL登录,:request_keys
也可以使用布尔值来表示是否需要密钥。
config.request_keys = { subdomain: false }
检查模型的设计调用中是否没有:validatable
如果您这样做,:validable将阻止具有相同电子邮件的多条记录,即使在不同的子域中也是如此。如果您想保留一些验证,可以从https://github.com/plataformatec/devise/blob/master/lib/devise/models/validatable.rb
复制所需的验证覆盖Devise auth finder hook
对于Authenticatable,Devise使用钩子方法Model.find_for_authentication。覆盖它以包含您的其他查询参数:
# app/models/user.rb
class User < ActiveRecord::Base
def self.find_for_authentication(warden_conditions)
where(:email => warden_conditions[:email], :subdomain => warden_conditions[:subdomain]).first
end
end
恭喜,用户登录现在限定为子域名!