[英]How to make cancan authorization gem limit users to their data they own?
[英]CanCan Rails How to Limit Users From Reading Data They Didn't Create
我在Rails 3.2應用程序中使用CanCan 1.6.1。 我在控制器中使用authorize_resource
來限制用戶可以進行:read, :create, :update: and :delete
。
在我的V2Posts controller
, authorize_resource
調用不適用於我的:show
動作。
在我的功能文件中,我試圖限制用戶只能閱讀他們自己的帖子。 沒有錯誤,但是很遺憾,他們能夠查看其他用戶的帖子。
class V2PostsController < ApplicationController
layout 'panel_layout', only: :show
before_filter :redirect_if_existing, only: [:new, :create]
authorize_resource
def show
@v2_post = V2Post.find(params[:id], include: :user_updates)
@organization = @v2_post.organization
respond_to do |format|
format.html
format.js
end
end
...
end
ability.rb:
class Ability
include CanCan::Ability
@user = nil
def initialize(user)
alias_action :taco,
:sandwich,
to: :read
@user = user
if user.is_in_role?(:admin)
can :manage, :all
else
default_rules
user.roles_list.each do |role|
meth = :"#{role}_rules"
send(meth) if respond_to? meth
end
end
end
def default_rules
cannot [:read, :create, :update, :destroy], :all
...
end
def pro_user_rules
can :read, V2Post, proid: @user.id
end
...
end
車型/ v2_post.rb:
class V2Post < ActiveRecord::Base
attr_accessible :proid, :user_updates_attributes, :organization
belongs_to :user, :foreign_key => "proid"
has_many :user_updates, as: :pro_post, dependent: :destroy
accepts_nested_attributes_for :user_updates
end
load_and_authorize_resource
用於阻止用戶查看其他用戶的帖子。 但是,它為我加載了資源,並且還將其他數據庫調用添加到其他操作中。 authorize_resource
是否適合我的情況? 我已經在show操作中明確定義了@ v2_posts(自己加載資源)。 為什么它沒有傳遞給authorize_resource
調用?
鑒於此, load_and_authorize_resource
和authorize_resource
哪個工作得更好,每個都有哪些好處/缺點? 我看了文檔,很困惑。
問題在於authorize_resource
是作為before過濾器運行的,並且直到在您的操作內部(在authorize_resource
調用之后)才設置實例。 當實例為nil時, authorize_resource
方法默認為對類V2Report
進行授權。 授權該類會忽略屬性條件(例如:可以讀取V2Report,user_id:@ v2_post.user_id)。
您可以使用load_and_authorize
資源,並在執行每個操作之前讓CanCan在控制器中設置實例變量。 對於以更復雜的方式加載資源的操作,例如您的V2Post.find(params[:id], include: :user_updates)
,您可以創建一個自定義的prepend_before_filter
方法來為某些操作加載資源。 只要是前提,該加載的實例將被傳遞到authorize_resource
方法。 如果實例已加載,則load_and_authorize_resource
將不會對數據庫進行其他調用。
class V2PostsController < ApplicationController
prepend_before_filter :custom_load_resource, only: [:show, :edit]
load_and_authorize_resource
def show
render @v2_post
end
private
def custom_load_resource
@v2_post = V2Post.find(params[:id], include: :user_updates)
end
end
您也可以完全忘記load_resource
,並在100%的時間內使用自己的before_filter。 或者,您可以放棄過濾器並致電authorize!
從動作中 根據我最近的經驗,上面詳述的方法對於RESTful控制器非常有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.