Ryota400’s blog

エンジニアを目指して書いてます。

アクション権限の調整

実装したこと

・記事投稿アプリで、管理者や編集者以外は記事の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」みたいにエラー用の画面が必要です。

参考文献

qiita.com

ログイン - はてな

magazine.rubyist.net