How to manage authorization in Ruby on Rails application?

Ali Sepehri
salamcinema
Published in
1 min readDec 16, 2016

I really hate to embed my authorization code into my business logic. There are some gems to prevent this evil. I’ve experience with pundit and cancan.

I need a completely action based authorization mechanism. Yes, pundit is action based authorization system.

I have some versions of APIs and I want the authorization mechanism support this structure. If you have different version of APIs for same models, in this case I have problem with pundit.

app
|_ controllers
|_ social
|_ news
|_ blog
|_ api
|_ v1
|_ post_controller.rb
|_ v2
|_ post_controller.rb

I need an authorization mechanism which supports my structure.

Maybe there is proper gem for my requirement but I can’t find it and I wrote my authorization method and put it into ApplicationController class.

def authorize?(record, query = nil)
controller_namespace = params[:controller]
.split('/')
.inject('') { |a, e| a + '::' + e.classify }
klass = "#{controller_namespace}Policy".constantize
policy = klass.new(current_user, record)
query ||= "#{params[:action]}?"
unless policy.public_send(query)
error = NotAuthorizedError.new(
"not allowed to #{query} this #{record}"
)
raise error
end
true
end

And my post policy class in app/policies/blog/api/v1/folder:

class Blog::Api::V1::PostPolicy < PolicyBase
attr_reader :user, :record
def initialize(user, record)
@user = user
@record = record
end
def destroy?
record.own_by? user
end
end

You can put your DRY codes in PolicyBase class. Now you can use this policy like the following:

class Blog::Api::V1::PostController < ApplicationController
def destroy
post = ::Post.find_by! uid: params[:uid]
authorize? post
# do your job
end
...
end

Thank You.

--

--