我有一个JavaScript对象,看起来像这样:

Const data = {
x: 1,
y: 2,
z: 3
a: 4,
b: 5,
c: 6
};


我们在Angular 6应用程序中提供了一个签名服务,该服务对这个对象进行字符串化处理,对字符串进行哈希处理,然后为其附加一个签名。然后将其保存到Firestore数据库。数据库喜欢按字母顺序对属性进行排序,因此最终看起来像这样:

{
a: 4,
b: 5,
c: 6,
x: 1,
y: 2,
z: 3
}


当我们从数据库中检索此对象并尝试验证签名时,它会失败。之所以失败,是因为当您对该对象进行字符串化时,与我们对其进行签名时相比,属性的字母顺序会导致生成不同的字符串。这将导致产生不同的哈希值,该哈希值与原始签名不匹配。

我们目前针对此问题的解决方案是,我们在代码中按字母顺序写出属性的顺序,但是我们想做一个简单的证明(例如,如果其他开发人员出现并在底部添加了一个属性,例如d,没有意识到它应该是按字母顺序排列的)。一位同事告诉我,有一种方法可以告诉Javascript根据其自己的算法对属性进行排序。如果可以做到,则在进行字符串化,散列和签名之前,应根据该算法对属性进行排序,然后在从数据库中检索对象时,请执行相同的操作:根据Javascript的算法对属性进行排序,进行字符串化,哈希和验证。

有人知道这个Javascript顺序是什么以及如何执行吗?

最佳答案

JS没有办法自然地订购对象,您将不得不自己修改它。

我想到的最简单的方法是使用数组并从那里排序。

这将返回以下数组...

Object.entries(test).sort((a, b) => a[1] - b[1])


退货

[ [ 'x', 1 ],
  [ 'y', 2 ],
  [ 'z', 3 ],
  [ 'a', 4 ],
  [ 'b', 5 ],
  [ 'c', 6 ] ]


如果您希望将其放回对象中,

Object.assign({}, ...Object.entries(test).sort((a, b) => a[1] - b[1]).map(([key, value]) => ({[key]: value})) )


退货

{ x: 1, y: 2, z: 3, a: 4, b: 5, c: 6 }

07-24 18:01
查看更多