0

Web3js frontend with Vue, .NET Core with Nethereum at the back.

The key target for this functionality is to sign a message at the frontend, send the signature and the address to the backend to validate that he actually owns that address.

The problem is that I keep ending up with varying address results. This definitely means that some part of my code is wrong. Anyone can spot the problem? <3

For the purpose of development testing, I've added the raw message as part of the API for now.

  1. Frontend

                  // Modern dapp browsers...
                  if (window.ethereum) {
                      // Propagate Web3
                      window.web3 = new Web3(ethereum);
                      await window.ethereum.enable();
                      window.ethereum.autoRefreshOnNetworkChange = false;
    
                      // Obtain the user accounts
                      let authMsg = 'This is a Nozomi auth message';
                      let accounts = await window.web3.eth.getAccounts();
    
                      // Ensure that the user is holding the wallet/s by asking him to unlock his
                      // account with a random message.
                      // https://ethereum.stackexchange.com/questions/48489/how-to-prove-that-a-user-owns-their-public-key-for-free=
                      if (accounts != null && accounts.length > 0) {
                          // https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop
                          // await Promise.all(accounts.map(async (account) => {
                          // }));
    
                          let shaMsg = window.web3.utils.sha3(authMsg);
                          let signed = await window.web3.eth.accounts.sign(accounts[0], shaMsg,
                              function (err, sig) {
                                  console.dir("Signature: " + sig);
                                  this.$buefy.notification.open({
                                      duration: 5000,
                                      message: `There was an error signing the validation request.`,
                                      position: 'is-bottom-right',
                                      type: 'is-danger',
                                      hasIcon: true
                                  });
                              });
    
                          console.dir("User signed data: ");
                          console.dir(signed);
    
                          // Validate the signed object on server side and provide an auth
                          let result = await axios({
                              method: 'post',
                              headers: { "Content-Type": "application/json"},
                              url: '/api/auth/ethauth',
                              data: {
                                  "claimerAddress": accounts[0],
                                  "signature": signed.signature,
                                  "rawMessage": authMsg
                              }
                          }).then(function (response) {
                              console.log(response);
                          }).catch(function (error) {
                              console.log(error);
                          });
    
                          console.dir("result: " + result);
                      }
                  }
    
  2. Backend

        public bool ValidateOwner(ValidateOwnerQuery request)
        {
            // Null Checks
            var addrValidator = new AddressUtil();
            if (request == null || string.IsNullOrEmpty(request.RawMessage) || string.IsNullOrEmpty(request.Signature) 
                || addrValidator.IsAnEmptyAddress(request.ClaimerAddress)
                || !addrValidator.IsValidEthereumAddressHexFormat(request.ClaimerAddress))
                return false;
    
            // Check for validity
            var signer = new EthereumMessageSigner();
    
            var resultantAddr = signer.EncodeUTF8AndEcRecover(request.RawMessage, request.Signature);
            return !addrValidator.IsAnEmptyAddress(resultantAddr) && resultantAddr.Equals(request.ClaimerAddress);
        }
    
0

Instead of using the web3.eth.accounts API, use web3.eth.personal to sign the message since you're using the user's address to sign the message, not his/her private key.

MetaMask verification on a server with web3.personal.sign

Instead of

let signed = await window.web3.eth.accounts.sign(accounts[0], shaMsg,
                          function (err, sig) {
                              console.dir("Signature: " + sig);
                          });

Do

let signed = await window.web3.eth.personal.sign(authMsg, accounts[0],
                              function (err, sig) {
                                  console.dir("Signature: " + sig);
                              });
|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.