使用cancan来防止对控制器的访问

12

我有一个管理员控制器,我希望只有被定义为管理员的用户才能访问该控制器。

我的权限类:

class Ability
  include CanCan::Ability

  def initialize(user)
    if user.admin?
      can :manage, :all
    else
      can :read, :all
    end
  end
end

我的管理员控制器:

class AdminController < ApplicationController
  load_and_authorize_resource

  def index
  end

  def users_list
  end
end

当我尝试访问/admin/users_list时(使用管理员用户或非管理员用户),我会收到以下错误:未初始化常数Admin

我做错了什么?这是限制控制器访问的正确方式吗?

5个回答

31
这是因为当你使用load_and_authorize_resource时,你的控制器必须由名为Admin的模型支持(因为你的控制器名为AdminController)。因此,你需要创建这个模型或者用以下内容替换load_and_authorize_resource

authorize_resource :class => false

这将导致访问检查针对你的操作而不是模型进行。请注意,这会不幸地导致一般的访问符号,如:manage:read停止工作,需要你在ability.rb中直接引用控制器操作:

can [ :index, :users_list ], :admin

其中第一个参数是用户可以访问的控制器操作的数组,第二个参数是控制器的短名称。

嗨,如果我想按类型拆分虚假的资源怎么办?例如,我的项目中有很多报告,但没有相应的模型。不同的视图都进入 reports_controller.rb 中的相同操作 build,具有特定的报告名称。我正在尝试像这样定义权限:can :read, :reports, name: ['Orders', 'Payments'] ,然后检查权限: if can? :read, :reports, name: 'Orders' 但是出现了错误 undefined method 'name' for :reports:Symbol。你有什么想法吗? - Andrey

7
您可以在控制器中设置授权。
authorize_resource :class => false

或者

authorize_resource :class => :controller

然后更改您的app/models/Ability.rb文件

can :manage, :controller_name

请参考此链接

3

1
这是因为当您创建一个通用控制器并使用load_and_authorize_resource时,应用程序控制器或管理员控制器无法找到实际的类,就像这个例子一样。这将起作用。
class Admin::HomeController < Admin::ApplicationController
    def home    
    end
  end

  class Admin::ApplicationController < ApplicationController
    load_and_authorize_resource :class => self.class
  end

0

我曾经遇到过同样的问题。我的解决方案是定义一个无法能力。与其定义只有管理员可以做什么,我正在定义非管理员用户不能做什么。在您的代码中,应该是这样的:

管理员控制器:

class AdminController < ApplicationController
 authorize_resource :class => AdminController

 def index
 end

 def users_list
 end
end

ability.rb:

class Ability
 include CanCan::Ability

 def initialize(user)
  if user.admin?
   can :manage, :all
  else
   can :read, :all
   cannot [:index, :users_list], AdminController
  end
 end
end

我刚学会了这种定义方法的可能性:can [:show], SettingsController if user.admin? 真是太棒了,谢谢! - alexventuraio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接