On a web page I have some 3 fields, name, age and height, which a user authenticated via MetaMask sends to backend along with his wallet address. In JSON.
In order to ensure that data that's sent hasn't been tampered and his wallet address indeed belongs to him, I'll have to ask a user to sign data, right? I'm aware of how to do it:
let mySigData = await this.mySigner.signMessage(ethers.utils.arrayify("some data"));
I'll also include a timestamp in data to prevent re-usage of a signature.
However, what is it what I actually will have to send from a client to then send to backend? What will all the data (data + payload) look like?
And how will I then deconstract it on a server properly?
Option #1
{
name: "name1",
age: 367,
height: 188,
sig: "fdsafdsafdsafds$$2fds####",
timestamp: 1236366
}
Option #2
{
sig: "#6$$,,##$$-safd8543gfds", //name, age and height have somehow been embeded here
timestamp: 1236366
}
I'm aware how to verify a signature itself in ether.js
but I mean the whole data itself.
On a server I'll then call …. what?
const verify = ethers.utils.verifyMessage("???", params["sig"])
Best Answer
As an example, your data structure could be:
Signing
To sign the
data
you must serialize it and the most simple serialization would be to useJSON.stringify
Recover Address
On the backend side, after receiving the user object, you should serialize the data in the same manner and recover the address with the signature:
Depending on your further logic you can check:
params.address
is equal to the recovered addressaddress
is allowed to submit dataThe most important key point here, regardless of the data structure you choose, is that it depends on your business logic. The serialization of the data takes place on the front end for signing. Subsequently, the raw data along with the signature is sent to the backend. The backend serializes the data in the same way and verifies if it can be retrieved for the expected address using the provided signature.