簡體   English   中英

CanCan Rails如何限制用戶讀取未創建的數據

[英]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 controllerauthorize_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調用?

  • 我想避免需要對數據庫的額外調用
  • 我不想自動加載用於自定義操作的資源
  • 我想授權每個CRUD動作。

鑒於此, load_and_authorize_resourceauthorize_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM