ruby-on-rails - rails : Is there any way to build dynamic role based authorization in rails?

标签 ruby-on-rails authorization roles role-base-authorization

我正在尝试在 Rails 中实现基于角色的授权。
我们需要什么:

  • 角色应该是动态的,我们应该能够创建、编辑或删除角色。
  • 权限也应该是动态的。

  • 调查结果:
  • 我们不能使用 pundit gem 因为它的策略是静态的,我们不能让它动态。
  • 我们可以使用 cancan gem,我们可以动态使用它,但我不知道如何完成?以及它如何与`数据库一起工作?

  • 这是我在授权部分的第一个项目。我们有 Rails 作为后端,vue.js 作为前端。无论有什么角色,数据库上的所有数据一开始都应该是空的。我们将使用种子创建 super 管理员角色并授予所有权限。 super 管理员会创建角色、编辑角色、销毁角色,最终还会添加权限、编辑和销毁权限。
    如果有任何其他有用的方法,请告诉我。
    谢谢。

    最佳答案

    Pundit 与 CanCanCan

    您关于 CanCanCan 和 Pundit 的结论纯属无稽之谈。它们都不是“静态”或“动态”,它们具有几乎相同的功能。不过,架构和设计理念完全不同。

    CanCanCan(最初是 CanCan)被写成 DSL,这是自 10 年前 Ryan Bates 创建 CanCan 时预切面包以来 HitTest 门的东西。它可以很好地按比例缩小并且易于学习,但是一旦您达到任何复杂程度,它就会变得非常丑陋。如果在 CanCanCan 中进行“动态授权”的任何事情由于其架构而将是一场噩梦。 CanCanCan中的能力类是所有神对象的神。

    Pundit 只是面向对象编程。在权威人士中,您的策略只是将用户和资源作为初始化参数并响应像 show? 这样的方法的类。 , create?等等。 Pundit 最初更难理解,但由于它只是面向对象编程,您可以根据需要对其进行定制。由于您的身份验证逻辑存储在单独的对象中,因此可以更好地扩展复杂性并遵守 SOLID 原则。

    如何设置动态角色系统?

    这是你的标准角色系统 ala Rolify:

    class User < ApplicationRecord
      has_many :user_roles
      has_many :roles, through: :user_roles
      def has_role?(role, resource = nil)
        roles.where({ name: role, resource: resource }.compact).exists?
      end
    
      def add_role(role, resource = nil)
        role = Role.find_or_create_by!({ name: role, resource: resource }.compact)
        roles << role
      end
    end
    
    # rails g model user_roles user:belongs_to role:belongs_to   
    class UserRole < ApplicationRecord
      belongs_to :user
      belongs_to :role
    end
    
    # rails g model role name:string resource:belongs_to:polymorphic
    class Role < ApplicationRecord
      belongs_to :resource, polymorphic: true, optional: true
      has_many :user_roles
      has_many :users, through: :user_roles
    end
    

    然后,您可以将角色范围限定为资源:
    class Forum < ApplicationRecord
      has_many :roles, as: :resource
    end
    

    Rolify 可以让您更进一步,只需将角色定义为一个类作为资源。例如user.add_role(:admin, Forum)这使用户成为所有论坛的管理员。

    如何创建权限系统?

    一个简单的RBAC系统可以构建为:
    class Role < ApplicationRecord
      has_many :role_permissions 
      has_many :permissions, through: :role_permissions 
    
      def has_permission?(permission)
        permissions.where(name: permission).exists?
      end
    end 
    
    # rails g model permission name:string
    class Permission < ApplicationRecord
    end
    
    # rails g model role_permission role:belongs_to permission:belongs_to
    class RolePermission < ApplicationRecord
      belongs_to :role
      belongs_to :permission
    end
    

    例如,您可以在 Forum.find(1) 上向“版主”授予“销毁”权限经过:
    role = Role.find_by!(name: 'moderator', resource: Forum.find(1))
    role.permissions.create!(name: 'destroy')
    role.has_permission?('destroy') # true
    

    虽然我怀疑它在现实中真的会如此简单。

    关于ruby-on-rails - rails : Is there any way to build dynamic role based authorization in rails?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60108114/

    相关文章:

    ruby-on-rails - rails : How to call one-to-one relationship in rails

    c# - 管理不同的用户角色 ASP.NET MVC

    c# - Store 没有实现 IUserRoleStore<TUser> UserManager<TUser>.GetUserRoleStore() ASP.NET Core MVC 3

    ruby-on-rails - 如何为不同类型的用户建模系统?

    ruby-on-rails - 阻止 Rails 尝试提供模板/ActionView::MissingTemplate

    ruby-on-rails - 没有属性的 Rails 完整错误消息

    ruby-on-rails - 部署后我看到标准 nginx 的 "It works!"

    git - 如何在没有ssh auth的情况下设置git服务器

    java - 如何管理eclipse git权限?

    flask - Flask-Login 是否支持角色?