【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 controller
にPundit
をinclude
します。
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.rb
にconfig.consider_all_requests_local = true
の記載があれば、403のエラー画面が確認できます。