我在ConsenSys为各种客户构建了大量的概念证明,通常他们想要利用以太坊区块链来解决某些业务用例。奇怪的是,这些系统通常设计有标准的网络登录(即用户名和密码)。我总是问自己为什么我还在这样做设计,毕竟,这是今天以太网目前可以解决每个烦人的Web应用程序的一个方面。所以我决定停下脚步,设计一下这个解决方案。

JSON Web token

登录标准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 beforevar 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 outres.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);...
}

我们终于搞定它了! 你的用户已经完全登录,但不需要密码。

UI方面

用户如何在浏览器中实际签署此数据?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,你就可以调用经过身份验证的端点。我们终于得到它了!

请注意,必须从签名中恢复vrs值。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扩展的任何用户都可以简单地绕过登录屏幕,其安全性可能比目前用于管理登录的任何内容都要好。这意味着更少的忘记密码,更少的浪费时间和更快乐的用户群。

而且,你知道,如果你希望你的用户在没有中间人的情况下向对方(或你或使用此用户的任何其他系统上的用户)付款,或者如果你想要利用以太坊的其他百万其他功能,那么你需要也这样做。

今天开始,加入我们以太坊,去征服世界。

======================================================================

分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:

  • java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
  • python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
  • php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。
  • 以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。
  • 以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
  • C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。
  • EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。
  • java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。
  • php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。
  • tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。

汇智网原创翻译,转载请标明出处。这里是原文不要再在以太坊和Metamask开发web时使用密码

以太坊和Metamask开发web应用时不再需要密码相关推荐

  1. 以太坊智能合约开发-《精通以太坊智能合约开发》学习总结实践

    文章目录 一.初探以太访智能合约 1. remix小demo 2. 写智能合约用的编程语言 二.以太坊核心概念 1. 交易/事务( Transaction ) 2. 区块 3. 共识协议:工作量证明( ...

  2. Python以太坊智能合约开发指南

    在以太坊上获得一个基本的智能合约是一个很简单的事,只需google查询"ERC20代币教程",你会发现有关如何做到这一点的大量信息.以编程方式与合约交互完全是另一回事,如果你是一个 ...

  3. 以太坊智能合约开发第二篇:理解以太坊相关概念

    链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. 很多人都说比特币是区块链1.0,以太坊是区块链2.0.在以太坊平台上,可以开发各种各样的去中心化应用,这些应用构成了以太 ...

  4. 以太坊智能合约开发:让合约接受转账

    以太坊智能合约开发:让合约接受转账 在以太坊智能合约开发中,通常会有向合约地址进行转账的需求,那么有几种向合约地址进行转账的方式呢? 有三种方式: 部署合约时转账 调用合约提供的方法 直接向合约地址进 ...

  5. 张家口以太坊智能合约开发实战pdf_以太坊的再次腾飞,你看得懂么?

    最近以太坊涨势明显,主要原因来源于一个平台对他的推广.那么,我们就来了解一下,这个平台是怎么回事儿.对以太坊的生态,会有什么样的帮助. ------------------------ FORSAGE ...

  6. 以太坊智能合约开发,Web3.js API 中文文档 ethereum web3.js入门说明

    以太坊智能合约开发,Web3.js API 中文文档 ethereum web3.js入门说明 为了让你的Ðapp运行上以太坊,一种选择是使用web3.js library提供的web3.对象.底层实 ...

  7. 以太坊中metamask、imtoken等钱包签名的php验证

    以太坊中metamask.imtoken等钱包签名的php验证 之前开发Dapp,需要用到以太坊钱包登陆dapp,找了很久没有这方面的库,加密算法倒是有很多,直接重新写了一个库,https://git ...

  8. 《如何五分钟创建自己的新币token 》Dapp开发 Web3+以太坊+智能合约开发 (一)

    Dapp开发 Web3+以太坊+智能合约开发 (一)如何创建自己的新币token 前言 就是想开发一个Dapp,实现一下功能.未来有可能的话建立一下自己的社区.话不多说直接开始: 开发自己的ETH代币 ...

  9. 一起学:以太坊智能合约开发

    课程介绍 无论在科技圈还是金融圈,"区块链"俨然成了最热的词汇.2016年,区块链写入了国家的十三五规划中:2017年,央行基于区块链技术的数字票据交易平台测试成功:同年,工信部发 ...

最新文章

  1. Qt Style Sheet 翻译(中)--类似css
  2. a股历史30年的大盘价_[最新]回顾A股历史上的大井喷行情
  3. 怎样查看电脑系统版本_微信7.0.0自动更新后怎样去还原以前的旧版本?
  4. Linq中的Where与SkipWhile
  5. Struts ActionForm简单理解
  6. 深度解析Java8 – AbstractQueuedSynchronizer的实现分析(下)
  7. 罗永浩:因为要烧投资人的钱 所以没有勇气再做手机了
  8. tensorflow保存数据为.pb格式和加载.pb文件(转)
  9. 杂谈(13)第二期办公技能交流分享活动深层次总结
  10. 【SpringBoot_ANNOTATIONS】AOP 01 AOP功能测试
  11. 华为手机 图标消失_华为手机升级EMUI 10后解决Google Play“消失”教程
  12. usb杂谈之获取设备信息——举例鼠标urb
  13. python 离线安装paramiko_离线安装 Python 2.7, paramiko 和 tornado
  14. ajax请求报415错误解决方案
  15. 1数字电路设计流程与SOC芯片架构图
  16. 有理数思维导图,七年级数学思维导图整理
  17. 如何打造团队的认同感
  18. 微信小程序-地区选择伪五级联动(选择国,省,市,县,镇)
  19. Uncaught (in promise) Error: Network Error at e.exports (axios.js:8:6410) at d.onerror (axio
  20. CodeSys轴控指令使用方法

热门文章

  1. ssacnf和sprintf实战取ip地址
  2. ARM汇编:汇编语言跳转指令: JMP、JECXZ、JA、JB、JG、JL、JE、JZ、JS、JC、JO、JP 等
  3. 常考数据结构与算法:平衡二叉树
  4. Vue 教程第十七 篇—— Vuex 之 module
  5. 安装ipvsadm 用make编译出现错误解决方法
  6. JavaScript精简代码 非一般的写法(转载)
  7. 利用源代码包搭建LAMP
  8. 负载均衡沙龙活动第二期现场问答汇集
  9. 好用的 Abyss Web Server
  10. Pyhton 模块和包