Rails Войдите, используя devise для аутентификации из двух таблиц db

У меня есть 2 таблицы базы данных, а именно coreteam и user. Обе модели настроены с devise. На данный момент, чтобы войти в основную команду, мой API: localhost:3000/api/v1/core_teams/sign_in со следующими данными запроса.

{ 
  "core_team": {
    "email": "[email protected]",
    "password": "Password21"
  }
}

И API для входа пользователей: localhost:3000//api/v1/users/sign_in со следующими данными запроса.

{
  "user": {
    "email": "[email protected]",
    "password": "Password20"
  }
}

И ниже мой файл route.rb

 Rails.application.routes.draw do

 root to: 'users#index'

scope 'api/v1', defaults: { format: :json } do
 devise_for :core_teams, controllers: {
   sessions: 'api/v1/sessions',
   passwords: 'api/v1/passwords'
  }

 devise_for :users, controllers: {
   sessions: 'api/v1/sessions',
   invitations: 'api/v1/invitations',
   passwords: 'api/v1/passwords',
   registrations: 'api/v1/registrations'
  }
  end
end

И я использую devise sessioncontroller для входа в систему. Единственная разница заключается в том, как я отображаю данные.

Мой session_controller.rb выглядит следующим образом:

module Api
 module V1
  class SessionsController < Devise::SessionsController
   private

    def respond_with(resource, _opts = {})
      render json: resource
    end

    def respond_to_on_destroy
      head :no_content
    end

   end
  end
 end

Теперь моя цель состоит в том, чтобы иметь только один вызов API для входа с использованием данных запросов того же типа. Причина наличия двух разных пользовательских таблиц заключается в том, что мое приложение является многопользовательским, а основная команда находится за пределами арендатора, а пользователи находятся внутри арендатора.

CoreTeam и архитектура арендатора


person Bhagawat    schedule 13.03.2020    source источник
comment
Я думаю, что если вы устанавливаете обезьяний патч, где устанавливается resource, лучше всего будет установить его для администратора или пользователя. Вы можете попросить клиентский FE отправить тип вместе с идентификатором, чтобы условно установить ресурс.   -  person Int'l Man Of Coding Mystery    schedule 13.03.2020
comment
Я бы просто установил один пользовательский класс и роли. Я никогда не понимаю, почему люди устраивают беспорядок на уровне аутентификации, когда они пытаются решить проблему авторизации.   -  person max    schedule 14.03.2020
comment
Причина наличия способов входа пользователя связана с такой архитектурой. Пользователь находится под арендатором (используя драгоценный камень квартиры), а CoreTeam находится вне арендатора.   -  person Bhagawat    schedule 15.03.2020


Ответы (1)


Попробуй это

маршруты

post "/api/v1/sign_in" => "api/v1/sessions#create"

devise_for :users, ...
devise_for :core_teams, ...

API/v1/sessions_controller.rb

module Api
  module V1
    class SessionsController < Devise::SessionsController
      before_action :rewrite_request_params, only: %i[create]

    protected
      def devise_mapping
        @devise_mapping ||= Devise.mappings[account_name || :user]
      end

    private
      def rewrite_request_params
        return unless account_name
        request.params[account_name] = {
          email: params[:email],
          password: params[:password],
        }
      end

      def account_name
        @account_name ||= account.class.name.underscore.to_sym if account
      end

      def account
        return if params[:email].blank?
        return @account if defined? @account
        @account = CoreTeam.find_by(email: params[:email]) || User.find_by(email: params[:email])
      end
    end
  end
end

это позволит вам отправлять параметры в /api/v1/sign_in как для User, так и для CoreTeam

Сначала он будет искать account в таблице core_teams, а затем в таблице users. если он будет найден, он перепишет request.params

# core_teams
$.post('/api/v1/sign_in', {
  "email": "[email protected]",
  "password": "Password21"
})

# users
$.post('/api/v1/sign_in', {
  "email": "[email protected]",
  "password": "Password20"
})
person PGill    schedule 17.03.2020