【问题标题】:do document IDs in Meteor need to be random or just unique?Meteor 中的文档 ID 需要是随机的还是唯一的?
【发布时间】:2015-06-30 15:21:25
【问题描述】:

我正在从 Rails 系统迁移数据,分配迁移对象 ID 非常方便,例如 post0000000000001 等。

我读过这里

Creating Meteor-friendly id's in Mongo?

Meteor 从

创建随机的 17 个字符串
23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz

看起来是为了避免可能出现歧义的字符(省略 1I 等)

出于某种原因,ID 是否需要是随机的?能够猜测 Meteor 文档的 ID 是否存在安全隐患?!还是只是一种生成唯一 ID 的简单方法?

Mongo 使用顺序 ID 看起来不错:

http://docs.mongodb.org/manual/core/document/#the-id-field http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/

所以我猜如果它存在的话,这将是一个 Meteor 约束。

【问题讨论】:

    标签: meteor


    【解决方案1】:

    ID 只需要唯一。

    通常有一个顺序元素:例如使用整数、时间戳或具有顺序性的东西。

    这在 Meteor 中不起作用,因为插入可能来自客户端,它们可能会断开一段时间,或者客户端时钟可能关闭/具有不同的延迟。由于延迟补偿(即时插入),在写入 _id 时也不可能知道之前的 _id(在顺序 _id 的情况下)。

    DDP 协议中缺乏顺序的后果是决定使用完全随机的 id。这并不是说您不能使用自己的 _id。

    虽然存在与此策略发生冲突的风险,但它在[number of docs in your collection]/[55^17] * 100 % 的数量级上是最小的,或者几乎是不可能的。如果发生这种情况,客户端将暂时插入它,并在服务器通过 Mongo Duplicate Key 错误确认错误后取消它。

    当涉及到其他答案的安全性时。如果用户的 _id 是已知的,这不是什么大问题。如果没有有效的散列登录令牌,则无法登录或使用它检索任何信息。当然,这仅适用于用户集合。如果您有自己的集合,则包含 id 作为参考的易于猜测的 URL 没有发布方法检查读取数据的资格是 Meteor 生成的高熵随机 id 可以减轻的风险。

    只要它们是唯一的,就可以使用您自己的 ID。

    【讨论】:

      【解决方案2】:

      我不是专家,但我认为 Mongo 需要一个唯一 ID,因此当它更新文档时,它实际上会创建具有相同 ID 的文档的新版本。

      真正的问题是——我也很想知道——我们是否可以在不破坏 Mongo 机制和可靠性的情况下更改 ID,或者我们需要创建辅助属性? (我想它也可以制作更小的索引)?

      但我也是,我可以想象,从安全角度来看,如果文档 ID 难以猜测,尤其是用户 ID,那就更好了!否则,在知道 ID 的情况下伪造用户是否容易或可能?如果我错了,任何人,请纠正我。

      【讨论】:

        【解决方案3】:

        我认为从 Mongo 更改 ID 是不可能且不可取的。

        但您可以使用 http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/ 轻松创建自动增量 ID

        function getNextSequence(name) {
          var ret = db.counters.findAndModify(
              {
                query: { _id: name },
                update: { $inc: { seq: 1 } },
                new: true
              }
         );
        
         return ret.seq;
        }  
        

        我已经创建了一个包,它可以做到这一点并且是可配置的。 https://atmospherejs.com/stivaugoin/fluid-refno

        var refNo = generateRefNo({
            name: 'invoices', // default: 'counter'
            prefix: 'I-',  // default: ''
            size: 5, // default: 5
            filling: '0' // default: '0'
        });
        console.log(refNo); // output: "I-00001"
        

        您现在可以使用refNo 在插入时添加到您的文档中

        也许对你有帮助

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-02-20
          • 2010-10-06
          • 2013-05-17
          • 2016-04-03
          • 2012-03-20
          • 2011-12-01
          • 2020-11-04
          • 1970-01-01
          相关资源
          最近更新 更多