Web3js

驗證使用者是否真正擁有該地址

  • February 27, 2022

Web3js 前端和 Vue,.NET Core 和 Nethereum 在後面。

此功能的關鍵目標是在前端對消息進行簽名,將簽名和地址發送到後端以驗證他確實擁有該地址。

問題是我不斷得到不同的地址結果。這絕對意味著我的程式碼的某些部分是錯誤的。任何人都可以發現問題嗎?<3

出於開發測試的目的,我暫時將原始消息添加為 API 的一部分。

  1. 前端
             // 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 &gt; 0) {
                     // https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop
                     // await Promise.all(accounts.map(async (account) =&gt; {
                     // }));

                     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);
                 }
             }
  1. 後端
   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);
   }

不要使用 web3.eth.accounts API,而是使用 web3.eth.personal 來簽署消息,因為您使用的是使用者的地址來簽署消息,而不是他/她的私鑰。

使用 web3.personal.sign 在伺服器上進行 MetaMask 驗證

代替

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

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

引用自:https://ethereum.stackexchange.com/questions/74759