Programming Journal

学習したことの整理用です。

【Rails】【Pundit】認可機能の追加

実装したいこと

  • 記事投稿アプリで、管理者以外は記事のCRUD機能を使用できないようにしたい。

  • 権限のないユーザーが該当のページにアクセスしたときは、403エラー画面を表示させる。

実装の流れ

  • Punditの導入
  • policyファイルの設定
  • Controller設定
  • View設定

  • エラー画面設定

前提

enumで、管理者adminと一般ユーザーwriterについて定義済み。
CRUD機能についても実装済

Pundit の導入

Punditを使えば、認可のシステムを簡単に実装することができます。
公式に沿って設定していきます。
GitHub - varvet/pundit: Minimal authorization through OO design and pure Ruby classes

Installation

gem "pundit"

ターミナルでbundle installします。

application controllerPunditincludeします。

class ApplicationController < ActionController::Base
  include Pundit
end

generatorを走らせると、policyファイルを生成してくれます。

rails g pundit:install

Policies

Policyファイルに認可を与えるユーザーについて設定していきます。
今回は、adminにだけ、認可を与えることにします。

class ArticlePolicy < ApplicationPolicy
  def index?
    user.admin? 
  end

  def create?
    user.admin?
  end

  def update?
    user.admin?
  end

  def destroy?
    user.admin? 
  end
end

クラスの継承について

クラスを継承している場合、継承元のPolicyに認可の設定をすれば、継承先でも適用されます。
私はそのことに気が付かずに、無駄に全ての継承先のPolicyファイルに同じ設定を記入してしまいました。。

Controller

def index
    authorize(Article)
end
(略)

View

権限の有無で、Viewファイルを表示させるかどうか判定

- if policy(Article).index?
              li
                = link_to articles_path do
                  i.fa.fa-folder-open
                  (略)  

エラー画面設定

publicディレクトリに403.htmlファイルをセットしておく。

<!DOCTYPE html>
<html>
<head>
  <title>Forbidden(403)</title>
  <meta name="viewport" content="width=device-width,initial-scale=1">
</head>

<body>
<p>You are not allowed to visit this page.</p>
</body>
</html>

config/application.rb
config.action_dispatch.rescue_responses["Pundit::NotAuthorizedError"] = :forbiddenを追記する。※公式にコードあり。

config/environments/development.rbconfig.consider_all_requests_local = trueの記載があれば、403のエラー画面が確認できます。