本篇内容介绍了“以太坊和Metamask开发web应用的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
登录标准Web系统(和/或使用其API)的一种非常流行的方法是将密码(经过哈希的客户端)提交给认证端点并接收token作为回报。这通常称为JSON Web Token,通常在一段有限的时间内(几分钟到几天)有效。这是一个关于标准实现的很好的教程。
JSON Web Token很好,我开始认为在区块链上验证自己很容易。事实上,当你使用以太坊时,你需要不断地去改进。
如果你将以太网地址(这只是公钥的sha3哈希)视为网站上的帐户,则可以通过使用私钥对一段数据进行签名来证明你拥有该帐户,这非常容易。此数据是任意的,可以是网站API提供的任意随机字符串。因此,我们可以使用地址作为用户名并绕过密码的需要。事实上,我们甚至不需要使用区块链来做到这一点。
这是使用Express的样子:
首先,我们需要使用私钥进行椭圆曲线签名:
var ethUtil = require(‘ethereumjs-util’); // >=5.1.1 var data = ‘i am a string’; // Elliptic curve signature must be done on the Keccak256 Sha3 hash of a piece of data. var message = ethUtil.toBuffer(data); var msgHash = ethUtil.hashPersonalMessage(message); var sig = ethUtil.ecsign(msgHash, privateKey); var serialized = ethUtil.bufferToHex(this.concatSig(sig.v, sig.r, sig.s)) return serialized
不要过分担心这些参数是什么。这里有一些密码学,我鼓励你阅读椭圆曲线签名。比特币维基是一个不错的起点。
无论如何,一旦我们有了签名组件,我们就可以将它们与用户的地址一起打包并将其全部发送到认证端点。
POST/Authenticate
var jwt = require(‘jsonwebtoken’); var ethUtil = require('ethereumjs-util'); function checkSig(req, res) { var sig = req.sig; var owner = req.owner; // Same data as before var data = ‘i am a string’; var message = ethUtil.toBuffer(data) var msgHash = ethUtil.hashPersonalMessage(message) // Get the address of whoever signed this message var signature = ethUtil.toBuffer(sig) var sigParams = ethUtil.fromRpcSig(signature) var publicKey = ethUtil.ecrecover(msgHash, sigParams.v, sigParams.r, sigParams.s) var sender = ethUtil.publicToAddress(publicKey) var addr = ethUtil.bufferToHex(sender) // Determine if it is the same address as 'owner' var match = false; if (addr == owner) { match = true; } if (match) { // If the signature matches the owner supplied, create a // JSON web token for the owner that expires in 24 hours. var token = jwt.sign({user: req.body.addr}, ‘i am another string’, { expiresIn: “1d” }); res.send(200, { success: 1, token: token }) } else { // If the signature doesn’t match, error out res.send(500, { err: ‘Signature did not match.’}); } }
所以基本上,给定一些数据,一个地址和一个EC签名的组件,我们可以安全的证明该地址属于签署数据的人。很酷,对吧?
一旦我们对签名和地址匹配感到满意,我们就可以为该地址服务器端签署一个JSON Web token。 在这种情况下,token有效期为1天。
现在我们只需要放入一些中间件来保护任何服务或修改受保护信息的路由。
middleware/auth.js
function auth(req, res, next) { jwt.verify(req.body.token, ‘i am another string’, function(err, decoded) { if (err) { res.send(500, { error: ‘Failed to authenticate token.’}); } else { req.user = decoded.user; next(); }; }); }
app.js
// Routes app.post(‘/UpdateData’, auth, Routes.UpdateData); …
如果提供的Token对应于发送请求的用户,我们将继续请求路由。请注意,中间件会修改请求。我们需要引用这个新的user
参数,因为我们知道它已经在我们的中间件中设置了。
POST/UpdateData
function UpdateData(req, res) { // Only use the user that was set in req by auth middleware! var user = req.user; updateYourData(user, req.body.data); ... }
我们终于搞定它了! 你的用户已经完全登录,但不需要密码。
用户如何在浏览器中实际签署此数据?Metamask会提供帮助!Metamask是一个整洁的chrome扩展,它将web3注入你的浏览器窗口。
mycomponent.jsx
makeSig(dispatch) { function toHex(s) { var hex = ‘’; for(var i=0;i<s.length;i++) { hex += ‘’+s.charCodeAt(i).toString(16); } return `0x${hex}`; } var data = toHex(‘i am a string’); web3.currentProvider.sendAsync({ id: 1, method: 'personal_sign', params: [web3.eth.accounts[0], data] }, function(err, result) { let sig = result.result; dispatch(exchange.authenticate(sig, user)) }) } } render(){ let { dispatch, _main: { sig } } = this.props; if (Object.keys(sig).length == 0) { this.makeSig(dispatch); } return ( <p>I am a webpage</p> ); }
这将触发Metamask弹出一个窗口,要求用户对消息进行签名:
一旦调用了回调,它将调用以下操作:
authenticate(sig, user) { return (dispatch) => { fetch(`${this.api}/Authenticate`, { method: 'POST', body: JSON.stringify({ owner: user, sig: sig}), headers: { "Content-Type": "application/json" } }) .then((res) => { return res.text(); }) .then((body) => { var token = JSON.parse(body).token; dispatch({ type: 'SET_AUTH_TOKEN', result: token}) }) } }
一旦你在reducer中保存了auth token,你就可以调用经过身份验证的端点。我们终于得到它了!
请注意,必须从签名中恢复v
,r
和s
值。Metamask有一个签名util模块,用于显示签名的构造方式。它可以像这样解构:
var solidity_sha3 = require('solidity-sha3').default; let hash = solidity_sha3(data); let sig = result.result.substr(2, result.result.length); let r = sig.substr(0, 64); let s = sig.substr(64, 64); let v = parseInt(sig.substr(128, 2));
其中r
将被解析为0或1.另请注意,这使用solidity-sha3模块来确保此哈希算法与用作solidity本机hash方法的哈希算法相同(我们正在hash之前签名的十六进制字符串))。
我无法强调使用JSON Web token的每个Web应用程序今天都可以轻松利用这一点。具有Metamask扩展的任何用户都可以简单地绕过登录屏幕,其安全性可能比目前用于管理登录的任何内容都要好。这意味着更少的忘记密码,更少的浪费时间和更快乐的用户群。
而且,你知道,如果你希望你的用户在没有中间人的情况下向对方(或你或使用此用户的任何其他系统上的用户)付款,或者如果你想要利用以太坊的其他百万其他功能,那么你需要也这样做。
“以太坊和Metamask开发web应用的方法是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。