cma*_*n77 4 ruby-on-rails devise warden
我的身份验证需要独立于:
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
Run Code Online (Sandbox Code Playgroud)
但我不清楚如何在登录支票上执行此操作。
谢谢!
In order do to do this you need to narrow the scope of the authentication to just the subdomain.
Here is a Docs page on how to accomplish this. I'll add it here for reference:
Overview
:subdomainfind_for_authenticationModify migration
First, you must remove the email index uniqueness constraint. Because we'll be turning this into a scoped query, we will scope the new index to subdomain. If this is a brand new Devise model, you can open the Devise migration and change the following:
# 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
Run Code Online (Sandbox Code Playgroud)
If this is an existing project, you'll need to create a new migration removing the old index and adding a new one:
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
Run Code Online (Sandbox Code Playgroud)
Change login keys
In your Devise model, add :subdomain to :request_keys. By default :request_keys is set to [].
# app/models/user.rb
class User
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, request_keys: [:subdomain]
end
Run Code Online (Sandbox Code Playgroud)
If you have multiple Devise models and you would like all of them to have the same :request_keys configuration, you can set that globally in config/initializers/devise.rb
config.request_keys = [:subdomain] # default value = []
Run Code Online (Sandbox Code Playgroud)
If additionally you want to still be able to log in using a URL without a subdomain, :request_keys can also take a hash with booleans indicating if the key is required or not.
config.request_keys = { subdomain: false }
Run Code Online (Sandbox Code Playgroud)
Check that you do not have :validatable in the devise call on the Model
If you do, :validatable will prevent more than one record having the same email, even in different subdomains. If you want to keep some of the validations, you can copy the ones you want from https://github.com/plataformatec/devise/blob/master/lib/devise/models/validatable.rb
Override Devise auth finder hook
For Authenticatable, Devise uses the hook method Model.find_for_authentication. Override it to include your additional query parameters:
# 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
Run Code Online (Sandbox Code Playgroud)
Congrats, User login is now scoped to subdomain!