7

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

redirect_to customers_path(session[:customer_id])

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

4

7 回答 7

14

假设您的 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来处理此逻辑。

于 2012-06-18T20:48:47.493 回答
10

我建议添加一个授权 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),则(非管理员)用户可以读取或更新订单。

于 2012-06-18T20:52:12.057 回答
1

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

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

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

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

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

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

于 2012-06-18T20:48:38.627 回答
1

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

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
于 2015-07-15T00:24:54.787 回答
0

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

于 2012-06-18T21:03:33.813 回答
0
(current_user.id == params[:id].to_i || is_writer?) || user_denied

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

于 2016-07-20T12:29:40.727 回答
0

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

def set_admin

end 

before_action set-admin only :[:destroy, :update]

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

于 2019-03-27T17:22:41.437 回答