无需身份验证的安全 Rails 3 MultiStep 订单的最佳方法
Posted
技术标签:
【中文标题】无需身份验证的安全 Rails 3 MultiStep 订单的最佳方法【英文标题】:Best approach for a secure Rails 3 MultiStep Order Form without authentication 【发布时间】:2011-11-15 10:37:34 【问题描述】:是的,我正在为不需要任何类型的用户注册或身份验证的网站构建订单。该表单具有三种模型:Order、OrderImage、Print。一个订单有很多 OrderImage,一个 OrderImage 有很多 Prints。
用户需要能够随订单上传图片 (OrderImage's),还需要能够在订单确认和提交之前返回并编辑每个 OrderImage。
表格是多步骤的,由四个阶段组成:
-
上传图片
审核上传
您的详细信息
确认上传
这很好,一切都按计划进行,并且随着用户输入更多详细信息或上传更多图像,数据会在整个订单过程中存储到数据库中。
但是,这意味着存在诸如“/upload?order=5”之类的 URL,这是不好的。因为没有身份验证,这意味着任何人都可能猜到订单的 URL 并更改它。
所以我只是想知道管理这个过程的最佳方法是什么?我有几个想法,但不确定它们是否是解决问题的最佳方法:
例如生成一个 6 位数以内的随机订单号,这样 url 就会更像:“/upload?order=645029”。这将导致有人猜测订单号的机会减少,但实际上仍然不是很安全。
将上述想法与订单状态相结合,例如“完成”。因此,当最终提交订单时,它被标记为完成。然后我可以防止再次访问任何“完成”订单。但是,在下单过程中,订单号还是有可能被猜测和篡改的。
利用会话并将订单号存储在此处而不是 URL 中,或作为表单中的隐藏值。
我看过 Ryan Bates 在多步表单上的 Railscast,他在会话中存储数据。然而,Ryan 本人也承认,以这种方式存储复杂的模型和对象是不切实际的。
因此,我们将不胜感激有关处理未经身份验证的订单的最佳方式的任何建议,谢谢。
【问题讨论】:
【参考方案1】:我会选择选项 #3。你说得对,在session中存储复杂的对象不好,但你只需要存储订单的ID号,然后你可以在数据库中查找。您可以使用before_filter
来确保请求的订单属于当前用户:
class OrdersController < ApplicationController
before_filter :check_ownership, :except => [:new, :create]
private
def check_ownership
redirect_to '/' unless params[:id] == session[:current_order_id]
end
end
以后可以轻松扩展此示例,以允许拥有帐户的用户查看他们的订单历史记录(而不仅仅是当前订单)。选项 #1 和 #2 只是掩盖了问题,以后可能会更难扩展。
【讨论】:
顺便说一句,如果您使用此示例,请注意类型。params[:id]
可能是字符串,session[:current_order_id]
可能是字符串或整数。【参考方案2】:
我不想回答一个问题...但是:当用户稍后返回网站时如何找到他的订单?
没有注册,你必须想办法将用户与订单关联起来!。
我看不出你怎么能安全地做到这一点,至少不问他一个唯一的用户名。
但是,任何人都可以猜出这个用户名并获得订单!
我想说,如果您不想进行身份验证...那么您不应该关心其他用户看到任何人的命令!
如果这是一个问题,您将需要一种简单的身份验证形式。
【讨论】:
用户在提交订单后不需要访问订单。提交后,订单将离线处理并开具发票。 @Cygnusx1,似乎并不要求用户在提交订单后可以访问他们的订单,但是通过电子邮件向用户发送带有生成访问令牌的链接真的很容易,例如,/orders/42?access_token=988881adc9fc3655077dc2d4d757d480b5ea0e11
.
好吧,我想我错过了..:“还有在订单被确认和提交之前返回并编辑每个 OrderImage 的能力。”我知道用户可以回来更改他的订单!但我猜你们都想在单个会话中执行此操作?
是的,抱歉,这可能不是很清楚。您的权利,用户需要能够在同一会话中编辑 OrderImage。
好的,我明白了... ;-) 在这种情况下,您可以像其他人已经提议的那样使用会话。祝你有美好的一天。以上是关于无需身份验证的安全 Rails 3 MultiStep 订单的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章