Day 14【连动 MetaMask - Front-End Request and Fetch】Modern problems require modern solutions

S__50708609.jpg

【前言】
嗨嗨感谢大家愿意看到这里,接下来要说的是前端的呼叫以及资料传递。今天的内容大部份都参考来自 Amaury Martiny 的 One-click Login with Blockchain: A MetaMask Tutorial!终於又可以回来用 web3.js 了,果然现代问题还是要用现代手段解决, web3.jsMetaMask@onboarding 是我的好朋友阿!

【Web3.js】
这里我们会使用到 JavaScript library web3.js 来引用 MetaMask 的相关 api。相关的介绍会在之後再做叙述!

npm install web3

import Web3 from 'web3';

web3.js - Ethereum JavaScript API - web3.js 1.0.0 documentation

【Front-End Request and Fetch】
在这边首先使用到 fetch 的功能来新增资料,需要注意的是要先在 .env 宣告 REACT_APP_BACKEND_URL=http://localhost:8000/api

const handleSignup = (publicAddress) =>
		fetch(`${process.env.REACT_APP_BACKEND_URL}/users`, {
			body: JSON.stringify({ publicAddress }),
			headers: {
				'Content-Type': 'application/json',
			},
			method: 'POST',
		}).then((response) => response.json());

这里可以跳出 MetaMask 的登入介面并且显示登入讯息,在取得 publicAddress 以及 nonce 之後显示出来。详细的步骤解释可以回去看 Day 10 有提到的 Login Flow。

const handleSignMessage = ({ publicAddress, nonce }) => {
    return new Promise((resolve, reject) =>
      web3.personal.sign(
        web3.fromUtf8(`I am signing my one-time nonce: ${nonce}`),
        publicAddress,
        (err, signature) => {
          if (err) return reject(err);
          return resolve({ publicAddress, signature });
        }
      )
    );
  };

authenticate 之中是传出 publicAddress 以及 signature,这将会在後端转译 signature 後比较这两者是否相同,来判断是不是登入成功。

const handleAuthenticate = ({ publicAddress, signature }) =>
    fetch(`${process.env.REACT_APP_BACKEND_URL}/auth`, {
      body: JSON.stringify({ publicAddress, signature }),
      headers: {
        'Content-Type': 'application/json'
      },
      method: 'POST'
    }).then(response => response.json());

将以上的函式放入按钮的函数之中。

const handleClick = async () => {
		...

		const publicAddress = coinbase.toLowerCase();
		setLoading(true);

		// Look if user with current publicAddress is already present on backend
		fetch(
			`${process.env.REACT_APP_BACKEND_URL}/users?publicAddress=${publicAddress}`
		)
			.then((response) => response.json())
			// If yes, retrieve it. If no, create it.
			.then((users) =>
				users.length ? users[0] : handleSignup(publicAddress)
			)
			// Popup MetaMask confirmation modal to sign message
			.then(handleSignMessage)
			// Send signature to backend on the /auth route
			.then(handleAuthenticate)
			// Pass accessToken back to parent component (to save it in localStorage)
			.then(onLoggedIn)
			.catch((err) => {
				window.alert(err);
				setIsLoading(false);
			});
	};

【小结】
这边我写的方法还是主要还是由 MetaMask Onboarding 为主,只是我目前还找不到方法在 MetaMask 的登入介面处显示 personal.signmessage 来告诉使用者当前的 nonce。这是比较可惜的地方,但是在後端的部分还是有纪录每个人的登入资讯!

直到这里就暂时结束登入系统的部分啦,接下来要开始学习 web.js 以及 ether.js 了!未来如果有用到相关的功能会随时回来这边做修改!

why_do_we_need_a_backend_why_not_just_connect_front_end_to_database.jpg

【参考资料】
One-click Login with Blockchain: A MetaMask Tutorial
Using Fetch - Web APIs | MDN

【在网站内部验证 MetaMask 并让使用者登入】
amaurym/login-with-metamask-demo: Demo project for "One-click Login with Blockchain: A MetaMask Tutorial"
Advanced Ethereum Dapp Series - Part 2 - React Hooks for Injected MetaMask, Web3.js and ethers.js
blockchain election dapp || part 2 react connectivity with metamask
MetaMask Tutorial: One-click Login With Blockchain Made Easy


<<:  找LeetCode上简单的题目来撑过30天啦(DAY11)

>>:  Day 11 - 用 canvas 复刻 小画家 多边形

Day4 - 如何设定预设交易帐号

在登入成功後,今天我们示范下单前,如何确认要使用哪个帐号交易。 *注1: Shioaji的各项功能(...

D28 - 压测

开始对TiDB进行测试,测试环境如下: 服务 vcpu ram 数量 TIDB/PD 8 20G 3...

Day 26 阿里云上运行Kubernetes 2 - ACK

接续昨天,我们建立完集群,也连上集群了来创立ngin服务吧 我们先查看一下丛集讯息 查看集群 kub...

[11] 建立进入页面和流程控制

这边你需要自己制作一个流程控制 不了解的话建可以画个图来确认现在在哪个流程 基本上都会回到主要操控介...

[DAY 24] _DMA简介

今天来说说我看了STM32_DMA的部分 DMA(Direct Memory Access,直接存储...