【问题标题】:Ruby on Rails: How to stop users changing url to view another user's page?Ruby on Rails:如何阻止用户更改 url 以查看其他用户的页面?
【发布时间】:2019-03-28 01:42:34
【问题描述】:

我已经得到它,以便客户页面上的显示视图链接到他们所下的所有订单。当他们单击“显示”时,它会将他们带到该订单的显示视图。但是,如果他们要更改 url 中订单的 id,他们就可以看到其他人的订单。请有人可以帮助或建议我可以使用它的方式,以便如果有人尝试查看他们被定向到的订单以外的订单,他们将被重定向到他们的客户页面?我可以让重定向位正常工作,使用:

redirect_to customers_path(session[:customer_id])

但是我如何让应用程序确保客户只能查看该订单?我似乎无法使用那种我检查订单 ID 是否等于 url 中的订单 ID 的逻辑,因为这将始终证明是正确的!

【问题讨论】:

    标签: ruby-on-rails authorization


    【解决方案1】:

    假设您的 Order 模型有一些“谁拥有这个订单”的概念,通常通过一个名为 user_id 之类的整数列,您可以检查 session[:customer_id] 是否等于 order.user_id(或任何您想要的叫它)。

    您通常会将此授权代码保存在您的控制器中。

    class OrdersController
      ...
    
      def show
        @order = Order.find params[:id]
        unless session[:customer_id] == @order.user_id
          flash[:notice] = "You don't have access to that order!"
          redirect_to customers_path(session[:customer_id])
          return
        end
      end
    
      ...
    end
    

    随着您的应用程序变得越来越复杂,您可能会查看像 CanCan 这样的授权 gem 来处理此逻辑。

    【讨论】:

    • 我建议从 CanCan 开始。如果您养成使用load_and_authorize_resource 的习惯,尽早添加它会更容易,并且会发现您可能忘记授权检查的地方。
    • 我实际上是在尝试将功能添加到现有应用程序中,以学习如何自己做事 - 不幸的是,考虑到 gems 构建为时已晚,但下次会考虑使用 CanCan,谢谢。
    【解决方案2】:

    我建议添加一个授权 gem,例如 CanCan,它可以让您设置用户是否有权执行某些操作(例如,编辑订单、查看订单等)。这可能会在很多方面派上用场;您可能希望拥有客户永远无法访问的管理页面(例如,用于添加新产品)。

    设置完成后,您可以限制客户的访问权限,以便他们只能查看或编辑自己的订单。在 CanCan 中,您创建了一个名为abilities.rb 的类,它看起来像:

    class Ability
      include CanCan::Ability
    
      def initialize(user)
        user ||= User.new # guest user (not logged in)
        if user.admin?
          can :manage, :all
        else
          can [:read, :update], Order, :user_id => user.id
        end
      end
    end
    

    关于can [:read, :update], Order, :user_id => user.id 的那一点意思是“如果 order.user_id == user.id”(即当前用户的 id),(非管理员)用户可以读取或更新订单。

    【讨论】:

    【解决方案3】:

    一个好的解决方案是首先删除相应的路线和视图。相反,为用户创建某种页面以查看他或她自己的订单。

    我不确定您使用的是哪个用户身份验证 gem,但如果您使用的是 Devise,您可以编写如下代码:

    <% current_user.orders.each do |order| %>
      <%= render order %>
    <% end %>
    

    如果您想保留当前视图和路由层次结构,可以在用户页面上使用此代码。

    <% if current_user.eql?(@user) %>
      <%= # show order history %>
    <% end %>
    

    如果不使用 Devise,我想编写一个 current_user 辅助方法来实现相同的功能不会太难。

    【讨论】:

      【解决方案4】:

      使用来自 Devise 的 current_user 助手、“IF”条件和不同的比较运算符 (!=) 对 @BinaryMuse 的解决方案进行轻微修改。

      def show
      @order = Order.find params[:id]
       if current_user.id != @order.user_id
          flash[:notice] = "MEAN MESSAGE HERE!"
          redirect_to orders_path(session[:current_user])
          return
        end
      end
      

      【讨论】:

        【解决方案5】:

        您也可以查看授权插件。最好设计它,以便您也可以用于其他功能。不要依赖客户端参数来查找用户的身份。更多信息在这里:http://www.rubyinside.com/authorization-permissions-plugin-for-rails-154.html

        【讨论】:

          【解决方案6】:
          (current_user.id == params[:id].to_i || is_writer?) || user_denied
          

          在我的情况下 is_writer? 检查用户是否可以修改订单 user_denied 是一个带有重定向和警报的方法

          【讨论】:

            【解决方案7】:

            基本上,您需要为用户创建 Rails 管理员或管理员并向其添加验证,然后在这些验证上设置管理员角色--

            def set_admin
            
            end 
            
            before_action set-admin only :[:destroy, :update]
            

            添加管理员时,将布尔值默认设置为 false

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-03-14
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多