Rails의 Strong Parameters 조사

10738 단어 RubyRails
레일스를 만지다가 스트롱 파라메터스를 발견해서 조사해봤어요.
초보자이기 때문에 잘못된 점이 있으면 지적해 주세요.

이 기사에서 하고 싶은 말

  • Strong Parameters는 DB에 들어오는 값을 제한함으로써 부당한 매개 변수의 입력을 방지하는 구조
  • Strong Parameters 개요


    Rails4 시스템에서 추가된 구조입니다.
    레일스3 계열까지 매스 어스젠트를 사용했으나 취약성 때문에 스트롱 파라메터스가 도입됐다.
    쉽게 말하면 DB에 넣거나 업데이트한 매개 변수를 제한하는 구조다.
    취약성에 관한 뉴스↓
    https://www.infoq.com/jp/news/2012/03/GitHub-Compromised

    기본용법


    예)
    params.require(:user).permit(:name, :email, :password)
    ① Require에서 POST에서 허용되는 값을 설정하는 키
    ② permit이 허용하는 열 설정
    여기서name, 이메일,password 속성의 값을 DB에 넣을 수 있습니다
    관리자 열이나 첨부도 무시합니다.
    참고로 strong parameters를 사용하지 않으면 rails가 틀릴 수 있으니 주의해야 합니다.

    리퀘어와 퍼미티를 쉽게 해독하기


    https://github.com/rails/strong_parameters/blob/master/lib/action_controller/parameters.rb
    잠깐 봤는데

    require


    parameters.rb
    def require(key)
      self[key].presence || raise(ActionController::ParameterMissing.new(key))
    end
    
    presence는 rails의 Object#presence 방법입니다.
    값이 존재하면self를 되돌려주고, 값이 없으면 가짜를 되돌려줍니다.
    Require 방법에서 수치가 없으면 오류가 반환됩니다.
    또한'[]'는 위에서 말한 바와 같이 다시 쓰여져 해시를 매개 변수로 변환하는 기능이 있다.
    parameters.rb
    def [](key)
          convert_hashes_to_parameters(key, super)
    end
    

    permit


    parameters.rb
    def permit(*filters)
      params = self.class.new
    
      filters.flatten.each do |filter|
        case filter
        when Symbol, String
          permitted_scalar_filter(params, filter)
        when Hash then
          hash_filter(params, filter)
        end
      end
    
      unpermitted_parameters!(params) if self.class.action_on_unpermitted_parameters
    
      params.permit!
    end
    
    이것은 실제적으로 DB가 받은 매개 변수를 필터에 하나하나 필터하는 작업이다.
    또한permit이 산열을 지정할 때 분해된 파라미터를 필터에 쓸 수도 있습니다.
    그 필터는 매개 변수의 종류가 허용되는지 확인할 수 있습니다.
    다음 Filterling 섹션에서는 허용되는 매개변수 유형을 설정합니다.
    parameters.rb
    PERMITTED_SCALAR_TYPES = [
      String,
      Symbol,
      NilClass,
      Numeric,
      TrueClass,
      FalseClass,
      Date,
      Time,
      # DateTimes are Dates, we document the type but avoid the redundant check.
      StringIO,
      IO,
      ActionDispatch::Http::UploadedFile,
      Rack::Test::UploadedFile,
          ]
    
    이 밖에permit에서 지정하지 않은 매개 변수는 여기에서 처리됩니다.
    parameters.rb
    def unpermitted_parameters!(params)  
      return unless self.class.action_on_unpermitted_parameters
    
      unpermitted_keys = unpermitted_keys(params)
    
      if unpermitted_keys.any?  
        case self.class.action_on_unpermitted_parameters  
        when :log
        name = "unpermitted_parameters.action_controller"
          ActiveSupport::Notifications.instrument(name, :keys => unpermitted_keys)
        when :raise  
          raise ActionController::UnpermittedParameters.new(unpermitted_keys)  
        end  
      end  
    end  
    
    def unpermitted_keys(params)  
      self.keys - params.keys - NEVER_UNPERMITTED_PARAMS
    end
    
    로그를 가져오거나 오류가 발생했습니다.
    기본적으로 로그가 나타납니다.
    오류를 출력하기 위해서는 별도의 설정이 필요합니다.
    NEVER_UNPERMITTED_PARAMS에는 rails에서 생성된 매개변수가 있으며 이는 제외됩니다.

    기타 strong parameters 사용 방법


    네스트된 매개변수 사용

    params.require(:user).permit(:name, :email, recommend_book: [:user_id, :comment])
    
    POST에서 매개변수를 네스트할 때 Strong Parameters 측면도 설정해야 합니다.

    지정한 키가 없을 때 오류가 발생하지 않습니다

    params.fetch(:user, {}).permit(:name, :email, :password)
    
    사용자 매개 변수가 없는 경우 Action Controller::Parameter Missing 오류가 발생합니다.
    상기 설정을 진행하면 {}을user 파라미터가 아닌 기본값으로 평가합니다.

    다른 매개 변수를 보내는 중 출력 오류


    각 환경의 configle로 설정합니다.
    출력하려는 환경에 따라 기술 설정을 변경하십시오.
    config/environments/development.rb
    config.action_controller.action_on_unpermitted_parameters = :raise
    
    Action Controller: UnpertedParameters 오류가 출력됩니다.

    참고 자료

  • http://b1840943.hatenablog.com/entry/2016/01/26/201316
  • http://morizyun.github.io/ruby/rails-controller-strong-parameters.html
  • http://o.inchiki.jp/obbr/181
  • 좋은 웹페이지 즐겨찾기