Rails: データベース内の 2 つの列に基づくユーザー認証が機能しないのはなぜですか?
概要
ホワイトラベル サービスを構築しているのですが、ユーザーが異なるドメイン (example1.com、example2.com) を介して同じ電子メールで認証できるようにするロジックが必要です。
Ruby-on-rails 6.1.7、ruby 2.7.0p0、デバイス 4.8.1 を使用しています。
私はこのドキュメントを使用してこれを実行しようとし、デバイス初期化子に次の行 config.authentication_keys = [ :email, :domain ] を追加しました。その後、インデックスを追加する移行ファイルを作成しました。
add_column :users, :domain, :string, null: false, default: 'example.com'
remove_index :users, :email
add_index :users, [:email, :domain], unique: true
Users モデルにも追加されました。
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable, authentication_keys: [:domain, :email]
def self.find_for_authentication
where(domain: warden_conditions[:domain], email: warden_conditions[:email]).first
end
新しいアカウントを作成する登録コントローラーは次のようになります。
def create
build_resource(sign_up_params)
resource.domain = request.domain
puts
puts '*' * 100
p resource
puts '*' * 100
puts
resource.save
yield resource if block_given?
if resource.persisted?
if resource.active_for_authentication?
sign_up(resource_name, resource)
else
render json: { success: true, location: '/registrations/success' }
end
else
render json: { errors: resource.errors.messages }, status: 422
end
end
今、私は問題に直面しています。データベースには、メールアドレス [email protected] とドメイン example1.com のアカウントがあるため、同じメールアドレスを持つ同じ人物に対して、別のドメイン example2 から新しいアカウントを作成しようとしています。 com このメールアドレスを持つユーザーが存在するというエラーが発生します。このデバイスがデータベースに対して間違ったクエリを実行していることがわかります。このクエリは次のようになります。 User Exists? (1.6ミリ秒) SELECT 1 AS one FROM “users” WHERE “users”.”email” = LIMIT [[“email”, “[email protected]”], [“LIMIT”, 1]] ですが、次のようになります。このユーザーは存在しますか? (1.6ミリ秒) SELECT 1 AS one FROM “users” WHERE “users”.”email” = AND “users”.”domain” = LIMIT [[“email”, “[email protected]”], [“domain”, “example.com”]、[“LIMIT”、1]]
見逃してしまったということでしょうか?助けていただきありがとうございます。
解決策
リンク先のページから