Model-level authorization in Rails

2019-06-28 07:51发布

I want to implement authorization in my Rails application on a model level (not controller), in a similar way that validation on models is done. What is the best way to do this?

If it is implemented in the models itself, the main problem is that the models don't have access to the current user. I've seen solutions like: Thread.current[:user_id] = session[:user_id], but that doesn't seem like a good idea.

I've seen a different approach where variants of the methods like create, find and new are created, accepting an additional parameter for the current user.

Another approach would be to implement all the methods in the User/role class, so for example user.posts.create or user.readable_posts.find would be used instead of Post.create or Post.find.

Which of these approaches would be suggested? Are there any better ways to implement the authorization? Are there any plugins that makes this easier? I need an approach that scales well for multiple roles and models.

2条回答
forever°为你锁心
2楼-- · 2019-06-28 08:47

Why would you do this? Isn't controller level identification enough?

if @user.is_able_to_do_this?
  do_this
else
  blah!
end

... and in your model

def is_able_to_do_this
  if self.rights > Constant::Admin_level_whatever
    return true
  end
  return false
end
查看更多
霸刀☆藐视天下
3楼-- · 2019-06-28 08:49

I would recommend you to look at declarative authorization. It works with both models and controllers.

The way it do what you are asking is having a before_filter in the applicationController that sets Authorization.current_user = current_user where Authorization is a module.

I think that approach is the best one, it keeps the models clean and you don't have to remember to include the user everywhere, but can filter it in the models callback functions instead.

查看更多
登录 后发表回答