我已经得到它,以便客户页面上的节目视图链接到他们放置的所有订单。当他们点击“显示”时,它会将他们带到该订单的展示视图。但是,如果他们要更改网址中订单的ID,他们就可以看到其他人的订单。请有人帮忙或建议我可以使用它的方式,以便如果有人试图查看他们被指示的订单以外的订单,他们将被重定向到他们的客户页面?我可以使用以下方法使重定向位正常工作:
redirect_to customers_path(session[:customer_id])
但是我如何获得应用程序以确保客户只能查看该订单?我似乎无法使用那种逻辑,我检查订单ID是否等于url中的订单ID,因为这总是证明是真的!
假设您的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,它允许您设置用户是否有权访问某些内容(例如编辑订单,查看订单等)。这可能在很多方面派上用场;您可能希望拥有客户永远无法访问的管理页面(例如,添加新产品)。
一旦准备就绪,您可以限制客户的访问权限,以便他们只能查看或编辑自己的订单。在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),“(非管理员)用户可以读取或更新订单”。
一个好的解决方案是首先删除相应的路径和视图。相反,为用户创建某种页面以查看他或她自己的订单。
我不确定您使用的是哪个用户身份验证gem,但如果您使用的是Devise,则可以编写如下代码:
<% current_user.orders.each do |order| %>
<%= render order %>
<% end %>
如果要保留当前视图和路由层次结构,可以在用户页面上使用此代码。
<% if current_user.eql?(@user) %>
<%= # show order history %>
<% end %>
如果不使用Devise,我想可以编写一个current_user辅助方法来实现相同的功能。
使用来自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
您还可以检查授权插件。最好设计它,以便您也可以使用其他功能。不要依赖客户端参数来查找用户的身份。更多信息:http://www.rubyinside.com/authorization-permissions-plugin-for-rails-154.html
(current_user.id == params[:id].to_i || is_writer?) || user_denied
在我的情况下is_writer?检查用户是否可以修改订单而不是user_denied是具有重定向和警报的方法
基本上你需要创建Rails管理员 - 或管理员给用户并添加验证,以便在这些验证上设置管理员角色 -
def set_admin
end
before_action set-admin only :[:destroy, :update]
添加admin时,默认情况下将boolean设置为false
我做到了这一点并且工作正常,我不知道它是否有帮助:
def show
user = User.find(params[:id])
redirect_to info_page_path unless current_user.id == @user.id
end