1

我最近将 cancan (1.6.9) 集成到我的 Rails (3.2.10) 项目中以进行授权,并且在 before_filter 中手动加载资源时遇到问题。这是我的场景的简要描述。

在 config/routes.rb 中,我有以下条目...

resources :users
match '/profile', :to => 'users#show'

这是我的 users_controller.rb 的样子......

class UsersController < ApplicationController
  before_filter :load_show_resource, :only => :show
  load_and_authorize_resource
  ...
  def show
  end
  ...
  private

    def load_show_resource
      @user = params[:id] ? User.find(params[:id]) : current_user
    end
end

如果我的 current_user 的 id 为 1,此代码将允许我访问 localhost:3000/users/1 但不能访问 localhost:3000/profile。

我的 cancan ability.rb 类中阻止此访问的条目如下所示 - 它是 cancan 部分。如果我注释掉无法条目,则两个网址都有效。

...
can [:show, :update], User, :id => user.id
cannot [:show, :update, :destroy], User do |u|
  u.site_id != user.site_id
end
....

不管 params[:id] 是否存在,不应该使用在 before_filter 中手动加载的资源来进行 show 操作吗?

有趣的是,如果我修改我的用户控制器(见下文)以使用 skip_load_and_authorize_resource :only => :show 并手动调用授权!在表演动作中,两个网址都有效。此外,如果我完全删除 cancan,则两个 url 都可以工作。

class UsersController < ApplicationController
  load_and_authorize_resource
  skip_load_and_authorize_resource :only => :show
  ...
  def show
    @user = params[:id] ? User.find(params[:id]) : current_user
authorize! :show, @user
  end
  ...
  private

    def load_show_resource
      @user = params[:id] ? User.find(params[:id]) : current_user
    end
end

所以,我的问题是为什么cancan 文档中的 Override loading 中解释的内容在这种情况下不起作用?

谢谢!

4

1 回答 1

0
# controller

class UsersController < ApplicationController
  load_and_authorize_resource, :except => :show
  # skip_load_and_authorize_resource :only => :show
  ...
  def show
    @user = params[:id] ? User.find(params[:id]) : current_user
    authorize! :show, @user
  end
  ...
end

# ability.rb

can [:show, :update, :destroy], User do |u|
  u.id == user.id && u.site_id == user.site_id
end
于 2013-03-17T09:18:29.090 回答