为只能通过该链接访问的链接创建唯一的令牌吗?

时间:2019-01-07 08:28:17

标签: ruby-on-rails ruby random

问题:下订单后,我会有一个订单确认页面。路线看起来像这样:

resources :orders do
      get 'order_confirmation', :on => :member
  end

链接

example.com/orders/1001/order_confirmation

相反,我想生成一个唯一的链接,如下所示:

example.com/orders/1001/order_confirmation/79sa9182-sd9871234123456f

因此,如果有人下订单1002,他们就不会“嘿,让我看看订单1001是什么”。

顺便说一句, order_confirmation 位于这样的OrdersController中:

  def order_confirmation
    @order = Order.find(params[:id])
  end

对于使用CanCanCan登录的用户,我确实对此具有安全性,但是我为未创建帐户且可能永远不会创建帐户的人员创建了order_confirmation页。

我该如何做到这一点,就像这样的链接:

example.com/orders/1001/order_confirmation/79sa9182-sd9871234123456f

已生成用于订单确认的链接,如下所示:

example.com/orders/1001/order_confirmation/

任何人都不能访问,甚至是购买者?


我确实找到了这个:Protected sharing link in Ruby on Rails

但是我不确定如何将其应用于订单确认页面,因为它没有自己的表或模型。它已经在OrdersController中了

3 个答案:

答案 0 :(得分:0)

我假设79sa9182-sd9871234123456f是代码或您存储在其他地方的其他东西。

然后,您需要像这样修改路线:

resources :orders do
  get 'order_confirmation/:code' => 'orders#order_confirmation', :on => :member
end

然后,您可以使用新路径创建指向订单确认页面的链接,例如:

your_new_path(id: <order_id>, code: <your_code>)

答案 1 :(得分:0)

使用friendly_id的好处-全部可用。如果您将use: [:slugged, :finders]添加到模型中,则无需担心使用什么-id或slug。这两个选项都起作用:

Order.find(1)
Order.find('my_first_order')

用friendly_id生成uuid并不是很常见的做法,因为我们已经在项目中添加了gem,所以我使用了它。看起来像:

class Order < ApplicationRecord
  extend FriendlyId
  friendly_id :blank_string, use: [:slugged, :finders]

  private

  def blank_string
    ''
  end
end

如果您不需要其他模型的子弹,则将新的token列添加到具有默认值default: 'uuid_generate_v4()'的订单表并在该列上进行索引会更容易。不要忘记启用扩展名'uuid-ossp'。

这是good article,介绍了uuid作为主键的优缺点。简而言之,它说:“两者兼具?内部是整数,外部是UUID”

答案 2 :(得分:0)

这就是我解决to_param问题的方式。我只是简单地删除了它,并为特定的成员路线重新组织了路线.....

使用时:

resources :orders, param: :order_token do get 'order_confirmation', :on => :member end

在我的路线中,我可以转到所需的URL。尽管在创建订单后,它仍然使用:id将我定向到一条路线。

然后我将重定向更改为:

redirect_to order_confirmation_order_path(@order.order_token)

它有效。

我还删除了to_param替代项。