Rails Admin не аутентифицируется с Cancancan или Devise - PullRequest
1 голос
/ 22 апреля 2019

Я попробовал это в конфиге:

  ### Popular gems integration
  config.authenticate_with do
    warden.authenticate! scope: :user
  end
  config.current_user_method(&:current_user)

здесь, доступ к /admin застревает в цикле входа в систему. Я захожу на сайт, после чего меня перенаправляют на страницу входа.

Ранее я пытался

class Ability
  include CanCan::Ability

  def initialize(user)
    # Define abilities for the passed in user here. For example:
    #
      user ||= User.new # guest user (not logged in)
      if user.admin?

с аутентификацией CanCanCan в конфигурации администратора rails. Это привело к тому, что пользователь всегда равен нулю. Даже когда я вставил

config.current_user_method(&:current_user)

Как мне исправить это, чтобы аутентификация была у администратора?

РЕДАКТИРОВАТЬ: в контроллере сессий

      if user.admin
        redirect_to rails_admin_url
      else
        render json: user
      end

и я застреваю в перенаправлении обратно, чтобы войти.

Маршруты:

Rails.application.routes.draw do
  mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
  devise_for :users, controllers: { sessions: :sessions },
                      path_names: { sign_in: :login }
... then many resources lines

EDIT:

Контроллер сеансов:

class SessionsController < Devise::SessionsController
  protect_from_forgery with: :null_session

  def create
    user = User.find_by_email(sign_in_params[:email])
    puts sign_in_params
    if user && user.valid_password?(sign_in_params[:password])
      user.generate_auth_token
      user.save
      if user.admin
        redirect_to rails_admin_url
      else
        render json: user
      end
    else
      render json: { errors: { 'email or password' => ['is invalid'] } }, status: :unprocessable_entity
    end
  end
end

Конфигурация админа Rails, пробуя это:

  ### Popular gems integration
  config.authenticate_with do
    redirect_to merchants_path unless current_user.admin?
  end
  config.current_user_method(&:current_user)

В ApplicationController:

def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end
  helper_method :current_user

Попробовал, current_user - ноль.

Ответы [ 2 ]

0 голосов
/ 01 мая 2019

ЛОГИКА КОНТРОЛЛЕРА ДЛЯ НАПРАВЛЕННЫХ

Решение от Guillermo Siliceo Trueba не будет работать с вашим действием Users::SessionsController#create, поскольку вы не звоните в родительский класс create действие через ключевое слово super.

Метод create из класса Devise::SessionsController будет запускать respond_with в последней строке, используя в качестве location значениевозвращается из after_sign_in_path_for(resource)

class Devise::SessionsController < DeviseController
  # POST /resource/sign_in
  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message!(:notice, :signed_in)
    sign_in(resource_name, resource)
    yield resource if block_given?
    respond_with resource, location: after_sign_in_path_for(resource)
  end
end

Я использую это решение в своих Users::SessionsController для обработки html и json запросов, и вы можете реализоватьто же самое.

Если контроллер получает request с форматом .json, выполняется код между format.json do .. end, если request приходит с format.html, вызывается родительский метод (я рассматриваювсе ваши сценарии).

Маршрутизатор Rails определяет формат запроса из .json или .html, добавленного в конце URL (например, GET https://localhost:3000/users.json)

class Users::SessionsController < Devise::SessionsController
  def create
    respond_to do |format|
      format.json do 
        self.resource = warden.authenticate!(scope: resource_name, recall: "#{controller_path}#new")
        render status: 200, json: resource
      end
      format.html do 
        super
      end
    end
  end
end

html запрос будет перенаправлен на super действие создания .Вам просто нужно переопределить метод def after_sign_in_path_for(resource) от родителя как , который я делаю в моем ApplicationController.

if resource.admin, затем просто return rails_admin_url из этого метода и пропустить другойв противном случае следуйте нормальному поведению и вызовите super#after_sign_in_path_for(resource)

def after_sign_in_path_for(resource)
  return rails_admin_url if resource.admin
  super
end

СООБЩЕНИЯ ОБ ОШИБКАХ ДЛЯ АУТЕНТИФИКАЦИИ

warned.authenticate! сохранит внутриself.resource.errors сообщения об ошибках.Вам просто нужно отобразить ошибки на вашем устройстве, используя json_response[:error] и манипулируя ответом в вашем интерфейсе.

Я отображаю их в SignInScreen Component

enter image description here

СИСТЕМА АУДИТОРИИ

user.generate_auth_token
user.save

Я использую simple_token_authentication для устройства , что также позволяетВы регенерируете токен каждый раз, когда пользователь входит в систему .

Вы просто устанавливаете драгоценный камень и добавляете acts_as_token_authenticatable в вашу user модель .

class User < ApplicationRecord
   acts_as_token_authenticable
end

Вы передаете заголовки X-User-Email и X-User-Token с соответствующими значениями, как объяснено в их руководстве .

Другие альтернативы simple_token_authentication

0 голосов
/ 22 апреля 2019

Возможно, вам потребуется определить метод after_sign_in_path_for в ApplicationController

По умолчанию сначала он пытается найти действительный ключ resource_return_to в сеансе, затем возвращается к resource_root_path, в противном случае он использует корневой путь. Для пользовательской области вы можете определить URL-адрес по умолчанию следующим образом:

get '/users' => 'users#index', as: :user_root # creates user_root_path

namespace :user do
  root 'users#index' # creates user_root_path
end

Если корневой путь ресурса не определен, используется root_path. Однако, если этого значения по умолчанию недостаточно, вы можете настроить его, например:

def after_sign_in_path_for(resource)
  stored_location_for(resource) ||
    if resource.is_a?(User) && resource.can_publish?
      publisher_url
    else
      super
    end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...