我相信您和我一样对 Web3 充满热情。本文介绍了一种新的区块链开发登录方法:使用 MetaMask 扩展的一键式加密安全登录流程,所有数据都存储在我们自己的后端。它还可以保护我们的数据和加密货币的安全。

在这里,我们将构建一个允许用户使用 MetaMask 登录的身份验证解决方案。

什么是MetaMask ?

MetaMask 是一个浏览器扩展和应用程序,将自己描述为加密钱包和区块链应用程序的网关。MetaMask 可作为浏览器扩展使用,您可以下载、安装和使用它。MetaMask 可帮助您管理控制您的以太坊地址的私钥,并促进加密交易和与区块链应用程序的交互。

他们的公共以太坊地址将用作唯一标识符,我们将使用 MetaMask 公开的私钥管理工具为用户提供一种机制来证明他们拥有该特定地址,从而有权以该用户身份登录。

先决条件

您需要先在浏览器中安装 Metamask 钱包Meta mask 网站。有了这个,您将可以访问一个独特的 Ethtereum 公共地址,您可以使用该地址开始发送和接收以太币或代币。但是,我们将通过连接到您的 metamask 钱包并显示信息来保持简单。

深入研究我们的代码

我们将创建一个新的 React 项目,并开始编写一些我们需要连接 Metamask 钱包的函数。

让我们从检测当前浏览器是否有 window.ethereum API 开始。MetaMask 将全球 API 注入其用户在 window.ethereum 访问的网站。该 API 允许网站请求用户的以太坊帐户,从用户连接的区块链中读取数据,并建议用户签署消息和交易。

window.ethereum

该 API 允许网站请求用户登录,从用户连接的区块链加载数据,并建议用户签署消息和交易。您可以使用此 API 来检测 web3 浏览器的用户。

window.web3

window.web3 仅在使用 http 或 https 协议查看页面时由 MetaMask 注入。因此,我们将检查这两个 API 是否已在网站中注入。

const detectCurrentProvider = () => {let provider;if (window.ethereum) {provider = window.ethereum;} else if (window.web3) {provider = window.web3.currentProvider;} else {console.log('Non-Ethereum browser detected. You should consider trying MetaMask!');}return provider;};

使用此功能,我们将知道我们是否有可用的 API,如果没有,我们将简单地记录消息。

让我们安装我们将要使用的 Web3 包。Web3.js 是以太坊区块链的 JavaScript 接口。

-获取链的最新区块(web3.eth.getBlockNumber)
-查看MetaMask上当前活跃的账户(web3.eth.coinbase)
-获取任何账户的余额(web3.eth.getBalance) –
-发送交易(web3.eth.getBalance) eth.sendTransaction)
-使用当前账户的私钥签署消息 (web3.personal.sign)

还有很多

我们现在将创建下一个函数,它将与 Web3.js 库通信并获取我们所需的信息。

 const onConnect = async () => {try {const currentProvider = detectCurrentProvider();if (currentProvider) {if (currentProvider !== window.ethereum) {console.log('Non-Ethereum browser detected. You should consider trying MetaMask!');}await currentProvider.request({ method: 'eth_requestAccounts' });const web3 = new Web3(currentProvider);const userAccount = await web3.eth.getAccounts();const chainId = await web3.eth.getChainId();const account = userAccount[0];let ethBalance = await web3.eth.getBalance(account); // Get wallet balanceethBalance = web3.utils.fromWei(ethBalance, 'ether'); //Convert balance to weisaveUserInfo(ethBalance, account, chainId);if (userAccount.length === 0) {console.log('Please connect to meta mask');}}} catch (err) {console.log('There was an error fetching your accounts. Make sure your Ethereum client is configured correctly.');}};

在上面的代码中,我们有一个异步函数,它将调用 Metamask 并获取我们请求的信息。我们想要获取有关我们的帐号、链 ID、帐户和 ETH 余额的信息。您可能还注意到我们还没有创建保存用户信息的功能。让我们创建一个将用户帐户信息保存到本地存储的函数,以便我们可以持久保存信息,除非断开连接。

 const saveUserInfo = (ethBalance, account, chainId) => {const userAccount = {account: account,balance: ethBalance,connectionid: chainId,};window.localStorage.setItem('userAccount', JSON.stringify(userAccount)); //user persisted dataconst userData = JSON.parse(localStorage.getItem('userAccount'));setUserInfo(userData);setIsConnected(true);};

我们创建一个函数,它接受三个参数并将信息保存到我们的本地存储中,这样我们就不会在用户不小心刷新浏览器时丢失。最后,使用 useState 内置钩子设置我们的本地状态。

取得了很大的进步,因为即使我们刷新也不会丢失信息,这暂时解决了我们的数据持久性问题。我们现在还需要添加我们的功能来删除从 loacalstorage 存储的信息。

const onDisconnect = () => {window.localStorage.removeItem('userAccount');setUserInfo({});setIsConnected(false);};

在上面的函数中,我们使用了当今所有浏览器都支持的 window 全局对象,并删除了存储在其中的对象和存储的键值。所有的事情都工作正常,但我们有一个问题。

我们连接到 Metamask 并检索钱包信息,但如果我们刷新,我们将丢失 UI 中的信息。为了处理这些信息,我们将使用内置的反应钩子 useEffect 来检查我们是否在窗口全局对象中有这个对象。

 useEffect(() => {function checkConnectedWallet() {const userData = JSON.parse(localStorage.getItem('userAccount'));if (userData != null) {setUserInfo(userData);setIsConnected(true);}}checkConnectedWallet();}, []);

在这里我们检查我们是否已经将密钥存储在本地存储中,如果是,我们将设置我们的本地状态,如果我们没有此信息,我们将返回 void。

我们在本文中介绍了一种一键式、加密安全的登录流程。我们只是触及了表面,Web3 必须为我们提供更多的可能性。