【问题标题】:How to use devise parent_controller for devise inherited controller but skip for ActiveAdmin devise controller?如何使用设计 parent_controller 设计继承的控制器但跳过 ActiveAdmin 设计控制器?
【发布时间】:2016-05-31 12:10:33
【问题描述】:

我正在开发基于 Api 的应用程序,site.com(客户端应用程序),api.site.com(服务器应用程序)

在我的 api.site.com 中,有密码、确认控制器,它们是从 Devise 控制器继承的。默认情况下,Devise 父控制器是 Application 控制器,但 Devise 继承的控制器需要通过 ApiBaseController api_authentication 动作。所以,Devise.rb 有如下配置:

config.parent_controller = 'ApiBaseController'

Api 身份验证现在工作正常。

ApiBaseController 示例代码:

class ApiBaseController < ApplicationController
  before_action :api_authentication

  def api_authentication
    api_key = request.headers['Api-Key']
    @app = Application.find_by_api_key(api_key) if api_key
    unless @app
     return render json: { errors: { message: 'Something went wrong, contact admin', code: '1000' } }
    end
  end
end

现在我正在使用 ActiveAdmin,安装 ActiveAdmin 后我尝试在浏览器上打开 http://localhost:3000/admin/login,我在浏览器上看到以下错误响应,而不是活动的管理员登录页面:

{"errors":{"message":"Something went wrong, contact admin","code":1000}}

我检查了问题,发现active_admin/devise/sessions 控制器也通过了 ApiBaseController。这是因为我们将父控制器设置为 ApiBaseController (config.parent_controller = 'ApiBaseController')。我删除了代码,ActiveAdmin 工作正常。

但是密码,确认控制器没有通过 ApiBaseController api_authentication(),因为我删除了设计配置 (config.parent_controller = 'ApiBaseController')。

所以如果你们已经理解了这个问题,请告诉我解决方案。

综上所述,我需要所有 api Devise 继承的控制器都需要通过 ApiBaseController 进行 api_authentication() 检查,而 ActiveAdmin Devise 控制器不需要通过 ApiBaseController。

提前致谢。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4 devise


    【解决方案1】:

    您只需在 application_controller.rb 中编写您的 api 身份验证逻辑,然后在您的密码控制器或任何您想要的地方使用 before_filter

    class ApplicationController < ActionController::Base
    
     private
    
     def api_authentication
        api_key = request.headers['Api-Key']
        @app = Application.find_by_api_key(api_key) if api_key
        unless @app
          return render json: { errors: { message: 'Something went wrong, contact admin', code: '1000' } }
        end
      end
     end
    

    并在您的控制器中使用before_filter :api_authentication

    class PasswordsController < Devise::PasswordsController
      before_filter :api_authentication
    
      .......
    end
    

    【讨论】:

    • 是的,但我不想在 ApplicationController 中添加任何代码,我们已经有了 ApiBaseController
    • 那么你可以在你的 api 基本控制器中使用before_action :api_authentication, if: :json_request?
    • 感谢您的建议,我会试试这个。顺便说一句,我解决了,我期待 Devise 的解决方案,因为我将来可能有很多像 ApiBaseController 这样的父母。
    【解决方案2】:

    我正在寻找在 Devise parent_controller 中添加条件的方法,但我没有为 Devise 找到任何解决方案。但是,我通过添加一些代码解决了它。

    class ApiBaseController < ApplicationController
      before_action :api_authentication
    
      def api_authentication
       return true if params[:controller].include?("active_admin/devise/")
        api_key = request.headers['Api-Key']
        @app = Application.find_by_api_key(api_key) if api_key
        unless @app
         return render json: { errors: { message: 'Something went wrong, contact admin', code: '1000' } }
        end
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-23
      • 1970-01-01
      • 2011-05-12
      • 1970-01-01
      • 2011-07-13
      • 2013-10-26
      相关资源
      最近更新 更多