概要
今日はRuby on Railsでよく使われる認可(Authorization)ライブラリ「Pundit」について学んだ。
- 認証(Authentication) → 「誰がログインしているか」(Deviseなど)
- 認可(Authorization) → 「誰が何をできるか」← Punditはこっち
特徴
- シンプルで軽量
- Policy クラス という純粋な Ruby オブジェクトで権限を管理
- テストが書きやすい
- Rails の規約に沿った設計
基本的な仕組み
1. インストール
# Gemfile
gem 'pundit'
bundle install
rails g pundit:install
2. ApplicationController に include
class ApplicationController < ActionController::Base
include Pundit::Authorization
end
3. Policy クラスを作成
app/policies/post_policy.rb
class PostPolicy < ApplicationPolicy
# 誰でも閲覧OK
def show?
true
end
# 自分の投稿だけ編集OK
def update?
user == record.user
end
# 管理者だけ削除OK
def destroy?
user.admin?
end
end
user→ 現在ログイン中のユーザーrecord→ 対象のモデルインスタンス(今回はPost)
4. Controller で authorize を呼ぶ
class PostsController < ApplicationController
def update
@post = Post.find(params[:id])
authorize @post # PostPolicy#update? が呼ばれる
# ...
end
end
権限がない場合は Pundit::NotAuthorizedError が発生する。
Scope(一覧の絞り込み)
class PostPolicy < ApplicationPolicy
class Scope < ApplicationPolicy::Scope
def resolve
if user.admin?
scope.all
else
scope.where(published: true)
end
end
end
end
# Controller
def index
@posts = policy_scope(Post)
end
よく使うメソッド
| メソッド | 説明 |
|---|---|
authorize @record |
Policy のアクションメソッドで認可チェック |
policy_scope(Model) |
Scope で絞り込んだコレクション取得 |
policy(@record) |
Policy インスタンスを取得 |
pundit_user |
現在のユーザーを返す(デフォルトは current_user) |
View での使い方
<% if policy(@post).update? %>
<%= link_to "編集", edit_post_path(@post) %>
<% end %>