好的,我正在为一个不需要任何类型的用户注册或身份验证的网站构建订单。该表单具有三个模型:Order、OrderImage、Print。一个订单有很多 OrderImage,一个 OrderImage 有很多 Prints。
用户需要能够将图像(OrderImage 的)与他们的订单一起上传,并且还需要能够在确认和提交订单之前返回并编辑每个 OrderImage。
表单是多步骤的,由四个阶段组成:
- 上传图片
- 审核上传
- 您的详细信息
- 确认上传
这很好,一切都按计划进行,随着用户输入更多详细信息或上传更多图像,数据会在整个订单流程中存储到数据库中。
但是,这意味着存在诸如“/upload?order=5”之类的 URL,这是不好的。因为没有身份验证,这意味着任何人都可能猜出订单的 URL 并更改它。
所以我只是想知道管理此流程的最佳方式是什么?我有几个想法,但不确定是否有任何想法是解决问题的最佳方法:
例如,生成一个 6 位以内的随机订单号,这样 url 就更像是:“/upload?order=645029”。这会减少有人猜测订单号的可能性,但实际上仍然不是很安全。
将上述想法与订单状态相结合,例如“完成”。因此,当最终提交订单时,它会被标记为完成。然后我可以防止再次访问任何“完成”订单。但是,在下单过程中,订单号仍然可以被猜测和篡改。
利用 session 并将订单号存储在此处而不是 URL 中,或作为表单中的隐藏值。
我看过 Ryan Bates 的 Railscast on Multistep forms,他在其中将数据存储在 session 中。然而,Ryan 自己承认以这种方式存储复杂的模型和对象是不切实际的。
因此,我们将不胜感激任何有关处理未经身份验证的订单的最佳方式的建议,谢谢。
最佳答案
我会选择选项 #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 只是掩盖了问题,以后可能更难扩展。
关于ruby-on-rails - 无需身份验证的安全 Rails 3 MultiStep Order Form 的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7390009/