Rails Войдите, используя devise для аутентификации из двух таблиц БД. - PullRequest
2 голосов
/ 13 марта 2020

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

{ 
  "core_team": {
    "email": "ba+admin@gmail.com",
    "password": "Password21"
  }
}

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

{
  "user": {
    "email": "ba+user@gmail.com",
    "password": "Password20"
  }
}

И вот мой файл rout.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 and Tenant Architecture

1 Ответ

1 голос
/ 17 марта 2020

Попробуйте

маршруты

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

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

api / v1 / session_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": "ba+admin@gmail.com",
  "password": "Password21"
})

# users
$.post('/api/v1/sign_in', {
  "email": "ba+user@gmail.com",
  "password": "Password20"
})
...