Techioz Blog

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]]

見逃してしまったということでしょうか?助けていただきありがとうございます。

解決策

リンク先のページから