1

我的项目中有一个用户模型和许多其他模型,以创建一个我实现角色和权限的 RBAC 系统。用户has_and_belongs_to_many角色和角色has_and_belongs_to_many权限。

class Permission
  include Mongoid::Document
  field :ability, type: String

  has_and_belongs_to_many :roles
  belongs_to :permission_for, polymorphic: true, dependent: :destroy

  index({ability: 1,permission_for_id: 1},unique: true)
end

class Role
  include Mongoid::Document

  field :name, type: String

  has_and_belongs_to_many :permissions
  has_and_belongs_to_many :users
  belongs_to :role_for, polymorphic: true

  index({name: 1,role_for_id: 1},unique: true)
end

在用户模型中我有:

Class User
  include Mongoid::Document
  .
  .
  .
  def able?(scope,model,action)
    # There must be something to load and check permissions
  end
end

角色定义在范围 ( role_for) 中,权限在角色范围内的模型中定义(项目是范围,任务是该范围内的模型)permission_for

在用户模型中,我需要从数据库中获取数据并检查用户是否能够执行该操作,在大量数据中需要太长时间。able?我实现的函数很简单,它只是加载每个用户的角色和每个角色的权限,然后检查权限的能力是否等于动作,然后返回true或false!

是否有任何宝石或代码可以做类似的事情?如果没有,你能给我建议如何以这种方式实现角色和权限,而数据库负载要少得多吗?

许多许多tahnk

编辑 1

好的,我已经创建了这个关系并设法在我的模型中使用它,正常使用的性能还可以,但是当我想要获取大量数据时,它非常慢。我需要在作用域模型中缓存角色和权限,我该怎么做?是否有任何 Rails 插件可以为我做到这一点?

4

1 回答 1

1

我们的产品接近软启动,我实施了该解决方案,但稍作调整:

我是如何完成 RBAC 的:


  项目 <--- 角色 <---> 权限 ---> 任务
                 ^(能力)
                 |          
                 |          
                 五          
               用户(能够?)               

此模式是最终实现的非常简化的版本,但概念相同

User.able?(model,ability)如果与模型相关的用户相关角色的所有权限的联合具有具有能力的权限,则返回 true。

    权限>>查看编辑删除
    V角色--------------------------------
     1 真假假
     2 真真假
     3假真假
                 --------------------------------
   结果真真假

我的用户有角色 1,2,3 然后用户可以viewedit但不能delete

为了解决性能问题和数据库命中使用俄罗斯娃娃缓存,对于每个角色,我缓存权限的哈希表示:

 role.get_permissions
 # returns {modelID => ['view'], model2ID => ['view','edit']}

然后为用户合并所有这些散列,并再次缓存该新散列。

在 User 类的方法的每次调用中,able?我都会得到那个哈希(从缓存中或者如果更改从数据库生成新的)和 Job Done :)

这种缓存最糟糕的问题是缓存过期。所以我们决定为我们的 ORM (MongoID) 添加新功能

从角色添加或删除权限将更新角色模型中的属性(不更新它的时间戳)

对于添加/删除/编辑角色的角色用户,我们这样做以及项目角色关系。

但是对于任务权限我们什么也没做,因为权限永远不会改变(能力和ID很重要)。

对于角色权限关系更新不会触发角色的 update_permission。

希望这有助于任何人达到这一点。

于 2013-10-18T18:42:35.990 回答