0

I have a JavaScript object that looks like this:

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

We have a signing service in our Angular 6 application which stringifies this object, hashes the string, then attached a signature to it. Then it saves it to a firestore database. The database likes to order the properties alphabetically so it ends up looking like this:

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

When we retrieve this object from the database and try to validate the signature, it fails. It fails because when you stringify this object, the alphabetical order of the properties results in a different string compared to when we signed it. This results in a different hash which doesn’t match with the original signature.

Our current solution to this problem is that we write out the order of the properties alphabetically in the code, but we’d like to make this fool proof (ex. If another developer comes along and adds a property to the bottom, say d, not realizing it’s supposed to be alphabetical). I’m told by a colleague that there is some way of telling Javascript to order the properties according to its own algorithm. If we could do that, then we’d order the properties according to that algorithm before stringifying, hashing, and signing, and then when we retrieve the object from the database, do the same thing: order the properties according to Javascript’s algorithm, stringify, hash, and validate.

Does anyone know what this Javascript ordering is and how to do it?

3
  • 7
    No. If you need guarenteed order, use an array Commented Feb 6, 2019 at 16:49
  • 1
    why not store the complete JSON string along or instead? Commented Feb 6, 2019 at 16:51
  • Usually I turn it into an array of key : value objects, then I order it by values Commented Feb 6, 2019 at 16:58

2 Answers 2

1

There isn't a way for JS to naturally order an object, you're going to have to tinker with it yourself.

The easiest way that I can think of to do this would be to use an array and sort from there.

This will return you the following array...

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

returns

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

If you want it back in an object,

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

returns

{ x: 1, y: 2, z: 3, a: 4, b: 5, c: 6 }
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I'll suggest this as a possible solution.
1

Create a custom stringify function that handles putting the object in the correct order.

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

function customStringify(d){
  return '{'+Object
  .entries(d)
  .sort(([,v1],[,v2])=>v1-v2)
  .map(([k,v])=>`${k}:${v}`)
  .join(",")+'}';
}

const res = customStringify(data);

console.log(res);

1 Comment

Thanks, I'll suggest this as a possible solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.