アクション権限の調整
実装したこと
・記事投稿アプリで、管理者や編集者以外は記事のCRUD機能を使用できないようにしたい。
・権限のないユーザーが該当のページにアクセスしたときは、403エラー画面を表示させる。
実装の流れ
・Punditの導入 ・policyファイルの設定 ・Controller設定 ・エラー画面設定
前提
role.rb
enum role: { writer: 0, editor: 10, admin: 20 }
Pundit
Punditは、リソースに対して、どのユーザーであれば処理が許可されるのかを定義するもの
インストール
Gemfile
gem "pundit"
bundle install
application controller
class ApplicationController < ActionController::Base include Pundit end
application controllerにPunditをincludeにする。
rails g pundit:install
generatorを走らせると、policyファイルを生成
Policyファイル
Policyファイルに認可を与えるユーザーについて設定していきます。
今回はadminとeditorに認可を与える
app/policy/article_policy.rb
class TaxonomyPolicy < ApplicationPolicy def index? user.admin? || user.editor? end def create? end def update? user.admin? || user.editor? end def destroy? user.admin? || user.editor? end end
クラスの継承
クラスを継承している場合、継承元のPolicyに認可の設定をすれば、継承先でも適用されます。
エラー画面設定
publicディレクトリに403.htmlファイルをセット public/403.html
<!DOCTYPE html> <html> <head> <title>権限がありません(401)</title> <meta name="viewport" content="width=device-width,initial-scale=1"> </head> <body> <p>権限がありません。</p> </body> </html>
config/application.rb
config.action_dispatch.rescue_responses["Pundit::NotAuthorizedError"] = :forbidden
config/development.rb
config.consider_all_requests_local = true
development環境ではconfig/development.rbで上記のような指定がされています。
この設定が「true」になっていると、いつも見るようなエラーの画面が表示されます。
開発環境ではこの画面が表示されることでデバッグができるので便利です。
config.consider_all_requests_local = false
もし開発環境でも「本番環境」と同じようにエラー用の画面を表示したい場合は「false」に変更して、サーバーを再起動します。
そうすれば、「ルートディレクトリ/public/」配下のエラー用の画面を表示できます。
なので、「404」エラーが発生した場合に、public配下に「404.html」みたいにエラー用の画面が必要です。
参考文献