【问题标题】:Ruby on Rails: The same check in multiple actions in a controllerRuby on Rails:控制器中多个操作的相同检查
【发布时间】:2012-01-17 19:08:14
【问题描述】:

如果这是一个重复的问题,首先我很抱歉。我试图找到答案,但由于我对 Rails 很陌生,我不知道要搜索什么。

我有一个控制器,上面有一些安全性。对于显示、编辑、更新和销毁操作,我需要检查用户是否拥有他们正在处理的角色,如下所示:

if @persona.user_id != @current_user.id

  flash[:notice] = "Sorry, we couldn't find that persona"
  redirect_to '/personas/'

else

  # do something else

这相对容易。但是,我如何以 DRY 方式执行此操作? else 之前的代码会在所有 4 个操作中重复,else 语句之后的代码将在每个控制器的基础上有所不同。

提前致谢。

理查德

【问题讨论】:

    标签: ruby-on-rails security model-view-controller


    【解决方案1】:

    您需要使用before_filter。像这样的:

    class PersonasController < ApplicationController
      before_filter :check_owner, :only => [:show, :edit, :update, :destroy]
    
      def show
      #...
      end
    
      #...etc.
    
      protected
    
      def check_owner
        redirect_to personas_path unless params[:id] == current_user.id
      end
    end
    

    另外,如果您还没有 @davidb 关于编写 current_user 方法的建议,该方法将在您的 application_controller.rb 中。像这样的:

    class ApplicationController < ActionController::Base
      helper_method :current_user
    
      def current_user
        @current_user ||= session[:user_id] ? User.find(session[:user_id]) : User.new
      end
    end
    

    您可能需要调整所有这些,因为这取决于您如何设置模型。这只是您需要/应该做什么的一般概念。

    【讨论】:

      【解决方案2】:

      使用before_filter这里是一个概述:

      http://guides.rubyonrails.org/action_controller_overview.html#filters

      你还应该写一个 current_user 方法来返回登录用户!

      【讨论】:

        【解决方案3】:

        您可以将安全逻辑移至 before_filter。它将在您的操作之前运行并进行安全检查。

        您的控制器文件:

        class TestController
        
           before_filter :check_persona, :only => [:show, :edit, :update, :destroy]
        
           private
        
              def check_persona
                 if @persona.user_id != @current_user.id
                    flash[:notice] = "Sorry, we couldn't find that persona"
                    redirect_to '/personas/'
                 end
              end
        
        end
        

        【讨论】:

        • 这可能不起作用,因为@persona 可能在调用before_filter 之后在方法中设置。
        • 也可以在 before_filter 中加载。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-09
        • 2017-10-27
        • 2015-09-29
        • 2012-04-02
        • 1970-01-01
        • 2013-08-16
        相关资源
        最近更新 更多