Rails 具有 Devise Admin 用户的管理员不适用于 API 仅应用程序

Rails Admin with Devise Admin user not working for API only app

我只有一个 API rails 应用程序,使用 Devise 进行用户管理,并使用 doorkeeper 从移动应用程序进行令牌授权。这很好用。

我还安装了 Rails Admin,以管理我数据库中的所有后端数据,它工作正常,我可以使用 Rails Admin 从我的浏览器和移动应用程序访问数据通过 API.

到目前为止,Rails 管理仪表板未受保护,我需要对其进行保护,以便只有管理员才能修改数据库中的数据。

我使用此 link https://github.com/plataformatec/devise/wiki/How-to-Setup-Multiple-Devise-User-Models

中的教程创建了另一个设计范围

但是当我输入 Rails Admin URL 时,页面从 devise 重定向到 /admins/sign_in,我认为这是正确的行为,但随后出现以下错误:

Started GET "/" for 186.2.132.186 at 2019-06-11 15:14:40 +0000
   (0.9ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
  ↳ /usr/local/rvm/gems/ruby-2.5.5/gems/activerecord-5.2.3/lib/active_record/log_subscriber.rb:98
   (0.9ms)  SELECT `schema_migrations`.`version` FROM `schema_migrations` ORDER BY `schema_migrations`.`version` ASC
  ↳ /usr/local/rvm/gems/ruby-2.5.5/gems/activerecord-5.2.3/lib/active_record/log_subscriber.rb:98
Processing by RailsAdmin::MainController#dashboard as HTML
Completed 401 Unauthorized in 10ms (ActiveRecord: 0.0ms)


Started GET "/admins/sign_in" for 186.2.132.186 at 2019-06-11 15:14:40 +0000
Processing by Admins::SessionsController#new as HTML
Completed 406 Not Acceptable in 16ms (ActiveRecord: 3.2ms)



ActionController::UnknownFormat (ActionController::UnknownFormat):

responders (2.4.1) lib/action_controller/respond_with.rb:213:in `respond_with'
devise (4.6.2) app/controllers/devise/sessions_controller.rb:14:in `new'

...more stack

在 Rails ADmin 初始化程序中,我添加了以下代码:

  ## == Devise ==
  config.authenticate_with do
    warden.authenticate! scope: :admin
  end
  config.current_user_method(&:current_admin)

这是我的路线:

#require 'api_constraints.rb'
Rails.application.routes.draw do

  use_doorkeeper do
   # No need to register client application
    skip_controllers :applications, :authorized_applications, :admins
  end

  #devise_for :admins, path: 'admins'
  devise_for :admins, controllers: {
          sessions: "admins/sessions",
          #registrations: 'admins/registrations',
      }, skip: [:registrations]

  mount RailsAdmin::Engine => '/', as: 'rails_admin'

  #devise_for :users
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
  scope module: :api, defaults: { format: :json }, path: 'api' do
    scope module: :v1 do
      devise_for :users, controllers: {
           registrations: 'api/v1/users/registrations',
       }, skip: [:sessions, :password]
    end
  end

   #Rutas para acceder al API
  #scope '/api' do
  namespace :api do
    namespace :v1 do
      resources :users
      resources :ejercicios
      resources :medidas
      resources :profiles
      resources :categoria_ejercicio
    end
  end

  root to: 'home#index'
end

我还在这个命令中包含了管理员的设计视图

rails g devise:views 管理员

能否就如何让它发挥作用给我一些提示或建议。谢谢。

问题

如您在日志中所见,/admin/sign_in 路径被拒绝并出现 406 Not Acceptable http 错误,这恰恰意味着请求的格式 (HTML) 未被接受。

Started GET "/admins/sign_in" for 186.2.132.186 at 2019-06-11 15:14:40 +0000
Processing by Admins::SessionsController#new as HTML
Completed 406 Not Acceptable in 16ms (ActiveRecord: 3.2ms)

发生这种情况是因为您在 API 模式下使用 Rails,而在此模式下 Rails 不再接受 HTML 请求。为了提高 APIs 的性能,一些中间件和模块被禁用。

问题是 Devise 需要 HTML 因为用户被重定向到表单。

解决方案

另一种方法是使用基本身份验证(Rails 为此提供帮助)。 我们通过基本身份验证(浏览器提示)获得凭据,然后我们仅使用 Devise 来验证用户。最后我们配置 Rails 管理员使用这个策略。

# rails admin configuration, replacing your existing config
config.authenticate_with do
  # this is a rails controller helper
  authenticate_or_request_with_http_basic('Login required') do |username, password|

    # Here we're checking for username & password provided with basic auth
    resource = Admin.find_by(email: username)

    # we're using devise helpers to verify password and sign in the user 
    if resource.valid_password?(password)
      sign_in :admin, resource
    end
  end
end

注意:您可能需要根据您的模型调整 resource = 行。我假设您已经有一个 Admin 模型。

代码未经测试,但这是一个开始。

资源: