Использование одного и того же адреса электронной почты для разных учетных записей в многопользовательском приложении с Devise - PullRequest
0 голосов
/ 18 марта 2020

TL; DR: в мультитенантном приложении с Devise пользователь должен иметь возможность зарегистрироваться с одним и тем же адресом электронной почты для разных арендаторов / учетных записей. Как я могу заставить Devise использовать account_id в User.find_for_database_authentication?


У меня мультитенантное приложение. Каждый поддомен принадлежит учетной записи со многими пользователями и администраторами (разные таблицы, нет наследования между ними). ​​

class User < ApplicationRecord
  belongs_to :account
  devise :database_authenticatable, :confirmable, :recoverable, :rememberable
  validates :email, uniqueness: true
end

class AdminUser < ApplicationRecord
  belongs_to :account
  devise :database_authenticatable, :confirmable, :recoverable, :rememberable
end

# config/routes.rb
scope module: 'auth' do
  devise_for :users, path: ''
  devise_for :admins, path: 'admin', class_name: 'AdminUser', ...
end

# /sign_in for users, /admin/sign_in for admins
# (you can log as both at the same time)

Думает, работает хорошо, но мне нужно разрешить пользователю входить в систему с тем же адресом электронной почты на разные арендаторы / аккаунты. Во-первых, я исправил проверку:

class User < ApplicationRecord
  validates :email, uniqueness: { scope: :account_id }
end

Проблема в том, что когда пользователь регистрируется / входит в систему, Devise будет искать первого пользователя с каким-либо адресом электронной почты, независимо от account_id, поэтому, если я использовать один и тот же адрес электронной почты на поддомене 1 и поддомене2, когда я захожу на поддомен2, я получаю информацию о пользователе от поддомен1 (что неверно)

  # config/initializers/devise.rb
  config.request_keys = [:subdomain]

  # app/models/user.rb
  def self.find_for_database_authentication warden_conditions
    joins(:account).where(
      email: warden_conditions[:email],
      accounts: {subdomain: warden_conditions[:subdomain]}
    ).first
  end

Этот вид работает, но я обнаружил две проблемы / недостатки:

  1. Когда я выхожу с пользователем, он делает то же самое с администратором (раздражает) для разработки)

  2. Я хотел бы использовать account_id на User.find_for_database_authentication и избегать JOIN. Я не знаю, как это сделать, поскольку Devise / Warden обрабатывает subdomain автоматически. warden_conditions ключи должны быть email и account_id.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...