[英]Rails authorization CanCanCan
我正在嘗試使用 CanCanCan gem 實現對路由的一些授權,但對於某些路由,它不起作用,並且它要么始終授權,要么根本沒有授權。
我只希望角色 id 為 5 (admin) 的用戶訪問價格控制器的更新操作,這是我的 ability.rb 代碼:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
# Define abilities for the passed in user here. For example:
if user.present?
can :show, User
if user.role.id == 5
can [:index, :update, :create], User
end
can :update, PricesController if user.role.id == 3
#
# The first argument to `can` is the action you are giving the user
# permission to do.
# If you pass :manage it will apply to every action. Other common actions
# here are :read, :create, :update and :destroy.
#
# The second argument is the resource the user can perform the action on.
# If you pass :all it will apply to every resource. Otherwise pass a Ruby
# class of the resource.
#
# The third argument is an optional hash of conditions to further filter the
# objects.
# For example, here the user can only update published articles.
#
# can :update, Article, :published => true
end
end
end
索引等的第一個操作正常工作,對於第二個操作,我調試了角色 id 也正確找到。 所以故障必須在我的控制器中,這是我的代碼:
def update
authorize! :update, current_user
if @prices.where(description: params[:description]).update(price_params)
respond_to do |format|
format.html { redirect_to prices_path }
format.json { render json: @prices }
end
end
end
如果我使用current_user
來檢查授權方法,每個人都可以更改值,如果我使用@prices
的實例變量,則沒有人可以執行控制器操作。
我也在處理異常:
rescue_from CanCan::AccessDenied do |e|
respond_to do |format|
format.html { redirect_to current_user, flash: { alert: "Sie besitzen dafür keine Berechtigung!" } }
format.json { render json: { success: false }, status: 401 }
end
end
我一遍又一遍地閱讀文檔,但我無法弄清楚我的錯在哪里。
一些不同的評論:
以你的能力.rb 我會說使用
if user.role.name == 'admin'
代替
if user.role.id == 5
除非您手動設置您的 id,否則您很可能必須更改它以進行生產。
還
can :update, PricesController if user.role.id == 3
應該
can :update, Price if user.role.id == 3
並在您的控制器中替換
authorize! :update, current_user
和
authorize! :update, Price
通常在 rails 更新操作中,您將只更新一個對象,並使用以下方法對其進行授權:
authorize! :update, @price
但在你的情況下,我猜想通過模型授權是你最好的途徑。
能力定義應該是:
can :update, Price if user.role.id == 3
您授權模型 - 而不是控制器。
調用授權時,您應該傳遞正在更新的資源實例或類(如果沒有實例):
authorize! :read, @thing
authorize! :index, Thing
但是控制器本身從根本上就以與 CanCanCan 無關的方式被破壞了。 這就是一切崩潰的地方:
@prices.where(description: params[:description]).update(price_params)
where
返回記錄的集合 - #update
是一種在單個記錄上調用的方法。 我不知道這是否是一次非常幼稚且失敗的大規模更新嘗試,或者您是否正在嘗試執行諸如 slug 列(漂亮的 url)之類的操作。 但是您可能應該堅持使用 rails 約定,直到您知道自己在做什么:
def update
@price = Price.find(params[:id])
authorize!(:update, @price)
if @price.update
# ...
else
# ...
end
end
在這種情況下,您也可以只使用load_and_authorize_resource
而不是手動查找和授權。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.