【问题标题】:Understanding how to use Pundit了解如何使用 Pundit
【发布时间】:2017-12-15 19:17:33
【问题描述】:

我一直试图围绕策略的概念展开思考,这似乎很简单——策略是一组规则,通过这些规则来确定对系统权限和资源的访问。

足够简单。

因此,为了让系统内的用户能够访问该系统内的所有其他用户的列表,他们需要必要的凭据(例如,可能是管理员或只是以注册用户身份登录)用户)。我什至在最基本的层面上都难以理解的是如何实际使用 Pundit 来实现这一点。就像我尝试学习的许多开源软件的文档一样,Pundit 文档似乎充其量只是暗示了该工具应该如何工作,但没有提供一个完整而具体的示例用例。我在这里寻找的只是一个“hello world”示例,因此我不会花三四天时间自己拼凑一个混乱且半途而废的实现,以实现这么小的东西。此外,Pundit 提供的例子只会让事情变得更糟。

我基本上创建了一个测试应用程序,它尝试结合使用 Devise(我似乎理解并且能够很好地使用它)和 Pundit。到目前为止:

  • 用户可以在网站上注册。
  • 用户可以登录和注销。

现在,我想做的——这是非常基本的事情,可能不应该这么快就让我皱眉头——是根据用户是否登录来限制用户对用户索引页面的访问进入系统,到这里我就完全卡住了。

到目前为止我尝试了什么?

  • 我已经按照文档安装了 Pundit。
  • 我已将 Pundit 包含在我的 application_controller.rb 中
  • 我生成了一个用户策略,如下所示:

    class UserPolicy < ApplicationPolicy
      class Scope < Scope
        puts "Inside UserPolicy scope."
        attr_reader :user
    
        def initialize(user)
          @user = user
        end
    
        def index
          puts "You've hit the index."
        end
    
        def resolve
          scope
        end
      end
    end
    
    
    class UsersController < ApplicationController
      before_filter :authenticate_user!
      after_action :verify_authorized
      def index
        @users = User.all
        authorize current_user
      end
    end
    

此时,我完全不知道如何关联这两者——UserPolicy 类和 UsersController。

我似乎至少能够在我的控制台上打印消息“在 UserPolicy 范围内”。但否则只会在浏览器中看到以下错误消息:

"不允许索引?这个#"

我遗漏了什么,如果没有别的,我自己的知识差距在哪里使这个和其他与 Rails 相关的工具如此难以学习?我是一名专业的软件工程师(从历史上看,我一直是一名前端工程师,并且在过去几年里一直在努力成为一名全栈工程师),但我发现自己经常被 open-像这样的源工具。

【问题讨论】:

    标签: ruby-on-rails ruby devise pundit


    【解决方案1】:

    您的实现存在一些问题:

    1. 动作授权(例如index?)进入父UserPolicy类,而不是内部Scope类。
    2. 授权调用的结果需要返回truefalse。您的index? 调用返回puts "You've hit the index.",其计算结果为nil
    3. 根据用户是否登录来控制访问是身份验证,而不是授权。 Pundit 仅应在用户通过身份验证后接管。

    【讨论】:

      【解决方案2】:

      Pundit 实际上只是设置在类似导轨的结构中的普通红宝石对象。

      我认为您的困惑是试图授权用户,更多地从资源的角度考虑。您正在通过某个安静的操作限制用户对某个对象的访问。范围限制了他们可以看到的内容,例如,管理员可能会执行 scope.all,单个用​​户可能不会被允许或只能在用户控制器上限定自己的范围。

      在我的应用程序策略中,我定义了帮手来对某些类型的用户进行分组。这是一个例子。

      class TicketPolicy < ApplicationPolicy
        class Scope < Struct.new(:user, :scope)
           def resolve
             #Allows government to see their organization
             # only allows citizens to see nothing
             if user.government?
               scope.where(:organization_id => user.organization_id)
             else
               scope.where(:id => 0)
             end
           end
        end
      
      
        def index?
          is_government
        end
      
        def show?
          is_government && is_inside_organization(@record)
        end
      
        def create?
          is_government && is_inside_organization(@record)
        end
      
        def new?
          is_government && is_inside_organization(@record)
        end
      
        def update?
          is_government && is_inside_organization(@record)
        end
      
        def edit?
          if user.employee?
            return is_mine(@record) && is_inside_organization(@record)
          end
          is_government && is_inside_organization(@record)
        end
      
        def destroy?
          false
        end
      end
      

      这限制了对组/角色的访问,然后在我的控制器中我只是调用

      authorize @thing
      

      然后权威人士将根据策略处理访问。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-23
        • 2023-03-11
        • 2021-07-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多