CanCan的替代方案是什么?

30

我目前正在使用rspec、devise和cancan。老实说,我发现cancan非常令人困惑,并且在学习和有效使用它方面遇到了很多困难。文档不够详细,这让我难以调试(请查看我的过去问题)。

是否有可以替代Cancan并且容易集成到我正在使用的其他工具中的选择?

10个回答

35
截至2014年初,Pundit是CanCan(以及后继者CanCanCan)的一个流行替代品。Pundit将每个控制器与一个策略对象进行匹配。与CanCan不同,没有一个用于所有访问控制的中央规则文件。它比CanCan更简单。RailsApps项目有一个示例应用程序:

Rails Pundit Example

我还写了一个关于Rails Authorization with Pundit的教程。
另一个选择是Nathan Long的Authority gem。所有的规则逻辑都在称为“authorizers”的Ruby类中,并与模型相关联。

1
谢谢!我也会关注标记为authority-gem的SO问题。 - Nathan Long
+1 对于您的支持。非常感谢您的工作,谢谢...!! - Sumit Munot
我也发现了"cancancan"和"the role"这两个宝石非常有用且活跃...!!! - Sumit Munot
我来这里是因为我想升级到Rails 4,并找到一个能够替代cancan并与devise集成的Rails 4兼容的授权系统。Pundit是合适的工具吗? - JohnMerlino
Pundit是与Rails 4.1和Devise集成的不错选择。请参见上面提到的示例应用程序。 - Daniel Kehoe
Pundit 真的很棒! - msdundar

7

4
出于同样的原因,我已经做了这个:http://mcasimir.github.com/checkin/Checkin 是一个独立于角色 /身份验证库的授权 gem。
你可以通过声明式 / 级联权限 DSL 来表达复杂的规则。
我发现它非常方便。还支持通过 explain 方法记录每个请求上的授权过程以进行调试。
以下是一些功能:
- 便捷的 DSL,使用声明式方法定义角色和权限 - 自动检查 CRUD 操作的授权 - 标准化的方式来解决授权错误 - 授权主体与模型分离(与任何身份验证系统兼容) - 基于角色的授权与角色系统分离(与任何角色系统兼容) - 当前用户和其他主体对象的装饰器 - 作用域授权规则 - 级联授权规则 - 简单易懂:即使是复杂的授权行为也能一目了然且易于预测 - 支持基于控制器的批量赋值保护
以下是 DSL 的一个非常简单的例子:
class UserSubject < Checkin::Subject

      role :guest, :alias => :anonymous do
          !subject_model
      end

      role :logged_in, :alias => [:connected] do
          !!subject_model
      end

      role :owner, :require => [:logged_in], :method => :own do |object|
          object && ( object.respond_to?(:author) && ( subject_model == object.author ) ) ||  ( object.respond_to?(:owner) && ( subject_model == object.owner ) )
      end

      role :administrator, :require => :logged_in, :alias => :admin do
          subject_model.has_role?(:administrator)
      end

      #
      # Permissions
      #

      permissions :for => :comments do
        allow :administrators
        allow :logged_in, :to => [:create]
        deny
      end

      # Admin

      scope :admin do
        permissions do
          allow :administrators
          allow :owners,  :to => [:edit, :update]
          deny
        end
      end

end

检查角色和权限:

subject = UserSubject.new(User.first, :scope => :admin)
subject.logged_in?
subject.guest?
subject.own?(Post.first)
subject.can_edit?(Post.first)

很抱歉我说话太啰嗦了。


3

也有一个 Railscast 可用。 - apneadiving

3

最好的...专家... - Sumit Munot

2

我目前正在探索Heimdallr。它最突出的特色是针对索引操作的受限范围,这是大多数cancan替代方案所没有的。


1

你可能也想要查看这个“超轻量级授权库” - six


这看起来很不错,并且似乎经常得到维护,不像CanCan已经几个月没有更新了!Rails 3.1兼容性如何? - Matheus Moreira
@Matheus Moreira 这是一个新的宝石,是在3-4周前发布的。它比caccan少了很多功能。代码库实际上只有一个文件。由于它不会向rails注入任何魔法,所以在rails 3.1上不应该有任何问题。 - rubish
自从我迁移到Rails 3.1以来,CanCan一直给我返回"method missing"错误,因此我决定将其替换掉,但我仍然没有完成软件的适应工作。我认为它可能会在特定情况下享有更好的与Rails集成,但也许最好留给一个单独的Gem,比如six-rails - Matheus Moreira
@Matheus Moreira 你可能想要查看这个[gist](https://gist.github.com/1175760) - rubish

1

请查看TheRole gem。这是 cancan 的一个非常有趣的替代品。


0

我建议使用Action Access,它更简单、直接,与Rails的无缝集成,非常轻量级。归根结底:

class ArticlesController < ApplicationController
  let :admin, :all
  let :user, [:index, :show]

  # ...
end

这将自动锁定控制器,允许管理员访问每个操作,用户仅显示或索引文章,任何其他人都将被拒绝并通过警报重定向。

如果您需要更多的控制,可以在操作中使用not_authorized!来检查和拒绝访问。

这使得控制器成为自包含的,与控制器相关的所有内容都在控制器内部。这也使它非常模块化,并避免了在重构时留下任何遗忘的垃圾。

它完全独立于身份验证系统,可以在没有User模型或预定义角色的情况下工作。您只需要为当前请求设置清除级别:

class ApplicationController < ActionController::Base
  def current_clearance_level
    session[:role] || :guest
  end
end

您可以返回您的应用所需的任何内容,例如 current_user.role

它还捆绑了一组方便的模型添加功能,允许扩展用户模型,并执行以下操作:

<% if current_user.can? :edit, :article %>
  <%= link_to 'Edit article', edit_article_path(@article) %>
<% end %>

这里的:article指的是ArticlesController,因此只有在当前用户被授权访问ArticlesController中的edit操作时,链接才会显示。它还支持命名空间

它允许默认锁定控制器,自定义重定向路径和警报消息等。请查看文档获取更多信息。


0

还有Consul

您可以创建一个Power类,其中的方法仅返回用户有权访问的对象,而不是加载对象并检查其权限。作者的演讲


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