레일즈의 인정 젬'펀디트'를 통해 빠짐없는 인정 설정 팁을 잘 만들 수 있습니다.

11622 단어 Rails
  • 응용 프로그램 내의 특정 데이터에 대해 "이 사용자에게 보여주고 싶지만 그 사용자에게 보여주고 싶지 않다"는 경우가 많다.
  • 이처럼'특정 사용자만 특정 행동을 허용한다'는 것을'인정'이라고 한다.
  • 이번에는'인정'을 할 때 편리한 젬Pundit을 설정하고 여러 가지 좋은 방법을 적어보고 싶어요.

  • 주의사항: Pundit에서 current_user(로그인 중인 사용자 취득) 방법을 사용하기 때문에 사전에 Devise Gem 등'인증체제'에 가입해야 한다.
  • Pundit의 개요

  • 먼저 젬pundit을 설치한 후 ApplicationControllerPundit 펀디트를 사용할 준비를 한다.( 창고 참조 )
  • class ApplicationController < ActionController::Base
      include Pundit
    end
    
  • 다음, 예를 들어'주인'과 관련된'양견 데이터'에 대해 다음과 같은'인정 설정'을 희망한다.

  • 이름이 기재된 에만 접근할 수 있습니다.
  • 로그인 중인 사용자가 사육자나 사육자의 지인일 때만 방문할 수 있다.
  • 이'방문'은 여러 가지 방법이 있는데 이번에는'Dog의 상세한 페이지 방문'상황에서만 고려한다.
  • 면 펀디트는 이렇게 쓸 수 있어요.
  • # app/policies/dog_policy.rb
    
    class DogPolicy < ApplicationPolicy
      # 必ずtrueかfalseを返すメソッドにする
      # recordにはデータ(対象となるDogインスタンス)が自動で入る
      # userはcurrent_userが自動で入る
      def show?
        dog_owner = record.owner
        record.name? && (dog_owner == user || dog_owner.friend?(user))
      end
    end
    
  • 이거 잘 알지 않아요?
  • 그리고 필요한 곳(주로 컨트롤러)에서 include에서 호출한다.
  • class DogsController < ApplicationController
      def show
        # ログインユーザーがアクセスできるのかチェック
        @dog = authorize Dog.find(params[:id])
      end
    end
    
  • 이 Gem의 똑똑한 점은 authorize에서 호출된 동작 이름과 모델 이름에서 자동으로 정책 방법을 선택해서 응용하는 것이다.
  • 이번에는 "authorize모델에 대한 Dog동작 내 호출"이기 때문에 자동으로 선택show한다.

  • 주의해야 할 것은 DogPolicy#show?가 되돌아오면show?authhorize는falseraise가 발생하기 때문에Pundit::NotAuthorizedError 등 오류를 줍고 403로 되돌아오는 메커니즘을 구축해야 한다는 것이다.
  • # app/controllers/application_controller.rb
    
    unless Rails.env.development?
      rescue_from Pundit::NotAuthorizedError, with: :render_403
    end
    
    def render_403
      # 中身は各自に任せる
      render template: 'pages/403', status: 403
    end
    

    Pundit 를 사용할 때 주의해야 할 점

  • 다음은 주제입니다.
  • 방금 코드를 되돌려줍니다.
  • # app/policies/dog_policy.rb
    
    class DogPolicy < ApplicationPolicy
      # 必ずtrueかfalseを返すメソッドにする
      def show?
        dog_owner = record.owner
        record.name? && (dog_owner == user || dog_owner.friend?(user))
      end
    end
    

  • 이거, 분석을 해보면 두 부분으로 나뉘어요.
  • 데이터의 상태와 관련된 조건문
  • 로그인 사용자와 관련된 조건문
  • 는 당연하다고 여겨질 수 있지만 인정된 코드를 쓸 때 이 두 가지를 엉망으로 만들면 인정의 누락과 오류 조작이 발생한다.

  • 이런 사태의 발생을 방지하기 위해서는 우선
  • 각자의 허가 설정에서 어느 조건(또는 두 가지)을 고려할 필요가 있다
  • 여러 조건이 있는 경우 "최강 구속"을 가하는 조건은 무엇입니까?
  • 잘 알 필요가 있어.

    예제


  • 나는 좀 복잡한 예를 하나 생각한다.
  • 는 이름이 기재된 에만 접근할 수 있다.
  • 는 각각에 대해'비공개 설정'을 할 수 있으며, 비공개 상태에서는 주인을 제외하고는 방문할 수 없다.
  • 다만, 사육사가'허가증'을 준 경우에는'비공개'도 방문할 수 있다.
  • 이런 상황에서 가장 먼저 통제해야 할 것은'어떤 조건이 가장 강한가'이다.
  • 예를 들어 이번 방법에서'의 이름이 없으면 페이지를 표시할 수 없다'는 경우'최강의 제한'은'에 이름이 기재된 것'이다.
  • 주인이라도 의 이름이 없으면 원래 페이지를 볼 수 없기 때문이다(프로그램에 영향을 미친다).
  • 그래서'있다'를 우선으로 한다.
  • class DogPolicy < ApplicationPolicy
      def show?
        record.name?
      end
    end
    
  • 다음에 무슨 생각을 하면'사주'또는'사주를 둔 Dog 열람 허가증'이 나온다.
  • '개 이름이 없다'외에 이 두 제약을 정할 수 있는 조건이 하나도 없기 때문이다.(비공개 설정과 상관없이 액세스 가능)
  • 따라서 다음은 이렇다
  • class DogPolicy < ApplicationPolicy
      def show?
        return false unless record.name?
    
        dog_owner = record.owner
        dog_owner == user || dog_owner.gave_license_to?(user)
      end
    end
    
  • 마지막으로 남은'공개할까 말까'조건문을 넣고 마무리했다.
  • class DogPolicy < ApplicationPolicy
      def show?
        return false unless record.name?
    
        dog_owner = record.owner
        return true if dog_owner == user || dog_owner.gave_license_to?(user)
    
        record.is_public?
      end
    end
    

    총결산

  • Pundit을 사용하면 권한 부여 설정을 쉽게 실현할 수 있다.
  • 허가 설정이 이뤄질 때만'강도의 순서'와'데이터의 조건이냐 로그인 사용자의 조건이냐'를 충분히 인식하고,'허가 검사 시 절차를 스토리로 삼는 것'이 중요해졌다.
  • 좋은 웹페이지 즐겨찾기