Hi Guest

More contents, please log on!

Bitmere.com 区块链技术 Content
    今天去中心化身份逐渐被广泛采用。用户的部分在线活动在链上是公开的,可通过加密钱包搜索到,用户在链上创造、贡献、赚取和拥有的东西,都反映了他们的喜好,也逐渐积累成该用户的身份和标识。

    当我们的用户厌倦了传统的电子邮件/密码注册流程时,他们会选择Google、GitHub等社交登录方式,这种方式虽然节约了用户的时间,但登录信息也会被第三方平台记录,也就是说我们用平台账号做了什么,平台都会一目了然,甚至还会对我们的行为进行分析、画像。那么有没有一种登录方式,它的所有信息都只保存在客户端和后端,并不牵扯三方平台授权,最大化的保证用户隐私呢?Web3.0给我们提供了一种选择:MetaMask。

    MetaMask
    MetaMask是用于与以太坊区块链进行交互的软件加密货币钱包。MetaMask允许用户通过浏览器插件或移动应用程序访问其以太坊钱包,然后可以使用这些扩展程序与去中心化应用程序进行交互。当然了,首先需要拥有一个MetaMask钱包,进入https://chrome.google.com/websto ... oehlefnkodbefgpgknn

    安装metamask浏览器插件:


  随后点开插件,创建账号,记录密码、钱包地址、以及助记词等信息。

    安装好插件之后,我们就可以利用这个插件和网站应用做交互了。

    钱包登录流程
    登录逻辑和传统的三方登录还是有差异的,传统三方登录一般是首先跳转三方平台进行授权操作,随后三方平台将code验证码返回给登录平台,登录平台再使用code请求三方平台换取token,再通过token请求用户账号信息,而钱包登录则是先在前端通过Web3.js浏览器插件中保存的私钥对钱包地址进行签名操作,随后将签名和钱包地址发送到后端,后端利用Web3的库用同样的算法进行验签操作,如果验签通过,则将钱包信息存入token,并且返回给前端。



前端签名操作
    首先需要下载前端的Web3.0操作库,https://docs.ethers.io/v4/,随后集成到登录页面中:


  1. <script src="{{ static_url("js/ethers-v4.min.js") }}"></script>
  2. <script src="{{ static_url("js/axios.js") }}"></script>
  3. <script src="{{ static_url("js/vue.js") }}"></script>
Copy the Code



这里我们基于Vue.js配合Axios使用。

    接着声明登录激活方法:

  1. sign_w3:function(){

  2.                     that = this;
  3.                     ethereum.enable().then(function () {

  4.     this.provider = new ethers.providers.Web3Provider(web3.currentProvider);

  5.     this.provider.getNetwork().then(function (result) {
  6.         if (result['chainId'] != 1) {

  7.             console.log("Switch to Mainnet!")

  8.         } else { // okay, confirmed we're on mainnet

  9.             this.provider.listAccounts().then(function (result) {
  10.                 console.log(result);
  11.                 this.accountAddress = result[0]; // figure out the user's Eth address
  12.                 this.provider.getBalance(String(result[0])).then(function (balance) {
  13.                     var myBalance = (balance / ethers.constants.WeiPerEther).toFixed(4);
  14.                     console.log("Your Balance: " + myBalance);
  15.                 });

  16.                 // get a signer object so we can do things that need signing
  17.                 this.signer = provider.getSigner();

  18.                 var rightnow = (Date.now()/1000).toFixed(0)
  19.         var sortanow = rightnow-(rightnow%600)

  20.         this.signer.signMessage("Signing in to "+document.domain+" at "+sortanow, accountAddress, "test password!")
  21.             .then((signature) => {               that.handleAuth(accountAddress,signature);
  22.             });

  23.                 console.log(this.signer);
  24.             })
  25.         }
  26.     })
  27. })

  28.                 },
Copy the Code
通过使用signMessage方法返回签名,这里加签过程中使用基于时间戳的随机数防止未签名,当前端签名生成好之后,立刻异步请求后台接口:

  1. //检查验证
  2.                 handleAuth:function(accountAddress, signature){


  3.                     this.myaxios("/checkw3/","post",{"public_address":accountAddress,"signature":signature}).then(data =>{

  4.                         if(data.errcode==0){
  5.                             alert("欢迎:"+data.public_address);
  6.                             localStorage.setItem("token",data.token);
  7.                             localStorage.setItem("email",data.public_address);
  8.                             window.location.href = "/";
  9.                         }else{
  10.                             alert("验证失败");
  11.                         }
  12.                  });



  13.                 }
Copy the Code
这里将当前账户的钱包地址和签名传递给后端,如图所示:




随后创建异步视图方法:
  1. from tornado.web import url
  2. import tornado.web
  3. from tornado import httpclient
  4. from .base import BaseHandler
  5. from web3.auto import w3
  6. from eth_account.messages import defunct_hash_message
  7. import time

  8. class CheckW3(BaseHandler):

  9.     async def post(self):

  10.         public_address = self.get_argument("public_address")
  11.         signature = self.get_argument("signature")

  12.         domain = self.request.host
  13.         if ":" in domain:
  14.             domain = domain[0:domain.index(":")]

  15.         now = int(time.time())
  16.         sortanow = now-now%600
  17.    
  18.         original_message = 'Signing in to {} at {}'.format(domain,sortanow)
  19.         print("[+] checking: "+original_message)
  20.         message_hash = defunct_hash_message(text=original_message)
  21.         signer = w3.eth.account.recoverHash(message_hash, signature=signature)

  22.         if signer == public_address:
  23.             try:
  24.                 user = await self.application.objects.get(User,email=public_address)
  25.             except Exception as e:
  26.                 user = await self.application.objects.create(User,email=public_address,password=create_password("third"),role=1)

  27.             myjwt = MyJwt()
  28.             token = myjwt.encode({"id":user.id})
  29.             self.finish({"msg":"ok","errcode":0,"public_address":public_address,"token":token})
  30.         else:
  31.             self.finish({"msg":"could not authenticate signature","errcode":1})
Copy the Code

   这里通过recoverHash方法对签名进行反编译操作,如果反编译后的钱包地址和前端传过来的钱包地址吻合,那么说明当前账户的身份验证通过:




当验签通过之后,利用钱包地址在后台创建账号,随后将钱包地址、token等信息返回给前端,前端将其保存在stroage中即可。

    结语

    没错,将至已至,未来已来,是时候将Web3.0区块链技术融入产品了,虽然有些固有的思维方式依然在人们的脑海挥之不去,但世界却在时不我待地变化着,正是:青山遮不住,毕竟东流去!项目开源在https://github.com/zcxey2911/Tornado6_Vuejs3_Edu


You have to log in before you can reply Login | 立即注册

Points Rules

Write the first review

江左没浪 小学生
  • Follow

    18

  • Following

    0

  • Articles

    7

59600
Promoted