Hyperledger Composer是一个用于在Hyperledger Fabric区块链平台上开发区块链应用程序的框架。
我们最近介绍了Hyperledger Composer入门,如果你不熟悉该技术,我建议你阅读如何使用Hyperledger Fabric和Composer构建区块链网络。在本文中,我们将执行以下操作:
- 创建示例业务网络定义。
- 使用Docker和PassportJWT身份验证生成Composer Rest服务器。
- 使用自定义JWT令牌使用Authenticated API。
要理解为什么这不是那么简单,你可以看看这个我一直密切关注的GitHub问题。
如果你熟悉Hyperledger Composer并且拥有示例网络,则可以直接跳转到Hyperledger Composer Rest Server部分。
先决条件
要继续学习,你应该安装以下内容。
1. Hyperledger Composer先决条件
这包括NodeJS LTS版本和Docker。你可以在本文档中找到适用于你的特定平台的说明。
安装完成后,你可以确认它们是否正常工作:
1 | docker -v |
2. Hyperledger Composer开发环境
这包括Composer CLI客户端:composer-cli
,Yeoman Generator:generator-hyperledger-composer
和yo
以及Hyperledger Fabric Docker镜像。我们将在Hyperledger Fabric实例部分中查看Hyperledger Fabric Docker镜像。
1 | npm install -g composer-cli yo generator-hyperledger-composer |
如果你使用Visual Studio Code进行开发工作,则可能需要安装Hyperledger Composer插件。
你可以在终端上输入composer命令确认已成功安装composer-cli:
1 | composer -v |
Hyperledger Fabric实例
在开始之前,我们需要运行Hyperledger Fabric的实例。Hyperledger Composer开发环境指南提供了有关如何启动网络的说明,但我们将简要介绍它。
创建一个名为fabric-dev-server
的目录,在终端内部拉出Hyperledger Composer提供的样本fabric-dev-server。
1 | cd fabric-dev-server |
应该有以下文件,这将有助于你快速启动Hyperledger Fabric实例。
1 | ls |
要启动实例,请首先下载Hyperledger Fabric镜像。
1 | ./downloadFabric.sh |
你将在系统中注意到以下新的Docker镜像。
1 | docker images |
接下来,启动Hyperledger Fabric实例。
1 | ./startFabric.sh |
这些脚本需要几分钟才能完成。它创建了一个composer_default
Docker网络,并在该网络中运行容器,以便它们可以通过自定义主机名进行通信。完成后,你可以通过检查正在运行的Docker容器来检查正在运行的Hyperledger Fabric的状态。
1 | docker ps |
为composer设置Hyperledger Fabric实例的最后一步是生成凭据。Composer允许你通过在.card
文件中保存相关信息来完成此操作。此文件通常基于连接配置文件生成,该配置文件在JSON文件中定义。我们下载的fabric-dev-server在文件fabric-dev-server/fabric-scripts/hlfv11/createPeerAdminCard.sh
中有文件。
编辑创建连接配置文件的部分(撰写本文时的第78行)。它开始于:
1 | cat << EOF > DevServer_connection.json |
编辑内容以使用主机名,而不是默认的${HOST}
。我们正在编辑的属性是orderers
,peers
和certificationAuthorities
。
createPeerAdminCard.sh
1 | ... |
与原始文件的不同之处在于我们已将${HOST}
替换为自定义主机名。我们正在做他的,因为Composer Rest Server将作为Docker容器运行,它将使用这个主机名访问网络中的相关容器。
但请注意,我们仍需要从终端访问同行,证书颁发机构和订购者。它们已经被Docker暴露在我们的主机上,并且正在侦听localhost上的特定端口。因此,我们需要将这些主机名的记录添加到/etc/hosts
文件中,以便在从我们的主机中调用时可以解析为localhost。你可能需要使用sudo
。
/etc/hosts
1 | ## |
现在,我们可以通过在fabric-dev-server目录中运行它来继续创建节点管理卡。
1 | ./createPeerAdminCard.sh |
要检查现有卡,请运行:
1 | composer card list |
商业网络
接下来,我们将创建一个示例业务网络。我们称之为tutorial-network
,与Hyperledger文档中给出的名称相同。
我们的业务网络将是Hyperledger Yeoman生成器生成的默认网络。我们没有改变它,因为这里的主要重点是验证Composer Rest Server。
我们将使用我们开始时安装的generator-hyperledger-composer
。使用以下内容,并在相关时进行更换。
1 | yo hyperledger-composer:businessnetwork |
这将生成一个名为tutorial-network
的目录,其中包含以下内容。
1 | . |
部署业务网络
创建业务网络后,我们将继续构建存档文件,并将其部署到Hyperledger Fabric的现有运行实例。
在tutorial-network目录的根目录中,创建业务网络存档。
1 | composer archive create -t dir -n . |
这将创建存档文件tutorial-network@0.0.1.bna
。
现在我们有了归档文件,我们可以继续将网络安装到节点中。运行此命令以安装网络:
1 | composer network install --card PeerAdmin@hlfv1 --archiveFile tutorial-network@0.0.1.bna |
接下来,我们通过运行启动网络:
1 | composer network start --networkName tutorial-network --networkVersion 0.0.1 --networkAdmin admin --networkAdminEnrollSecret adminpw --card PeerAdmin@hlfv1 --file networkadmin.card |
此命令可能需要一段时间才能运行,但是当它完成时,你会注意到一个新的Docker容器,其名称以dev-peer0.org1.example.com-tutorial-network-0.0.1 ...
开头。运营我们的业务网络。你可以通过运行docker ps
来检查这一点。
然后,我们需要导入新的networkadmin卡,以使其在网络中可用。
1 | composer card import --file networkadmin.card |
你得到一个networkadmin卡名称admin@tutorial-network
,我们可以继续使用它。你也可以通过运行composer card list
来检查。
最后,为了确保成功部署业务网络,我们可以ping下试试。
1 | composer network ping --card admin@tutorial-network |
业务网络默认参与者。
由于本文的目标是创建一个经过身份验证的Composer Rest服务器版本,因此我们将创建一个默认参与者,他们将能够创建其他参与者和身份。
/fabric-dev-servers/tutorial-network/models/org.example.biznet.cto
文件中参与者的结构是:
1 | participant SampleParticipant identified by participantId { |
我们将创建一个参与者并将其绑定到一个身份,以便我们为该参与者获得一张身份证。这是我们要添加的参与者。
1 | { |
在终端中定义参与者数据。
1 | participantId=gangachris |
然后将参与者添加到网络中。
1 | composer participant add -c admin@tutorial-network -d "$participantData" |
然后我们需要向该参与者发放身份,以便他们拥有身份证。
1 | composer identity issue -c admin@tutorial-network -f gangachris.card -u $participantId -a "resource:${PARTICIPANT_CLASS}#${participantId |
-x
标志允许参与者能够发出身份。
Hyperledger Composer Rest服务器(Docker)
部署Composer Rest Server最常见的生产方式是通过Docker。 这主要是因为Hyperldger Fabric实例部署主要通过Kubernetes,Docker在容器网络生态系统中运行。 Swarm或普通的docker-compose样式就像我们现在正在做的那样。
由于我们使用的是passport-jwt
,我们需要创建一个我们将在Docker容器中添加的自定义JWT文件。
custom-jwt.js
1 | // based on: |
我们在这里没有添加任何JWT声明,因为我们正在努力使其尽可能简单。我们从请求授权header`passportJwt.ExtractJwt.fromAuthHeaderAsBearerToken()中检索JWT作为承载token,并且库将处理剩余的身份验证。
请注意,我们将从其他地方生成JWT token,可能是将使用Composer Rest Server的客户端。对于Composer Rest Server解码token并为其提供自己的访问token,用于生成原始JWT token的JWT秘密必须用作passport-jwt配置的秘密变量,我们将在稍后看到。
Composer Rest Server还要求JWT token声明具有ID或用户名。(不知道为什么会这样)。
然后,我们将为Composer Rest Server构建一个Docker镜像。创建一个Dockerfile。
Dockerfile
1 | FROM hyperledger/composer-rest-server:0.19.5 |
我们将安装passport-jwt和loopback-connector-mongodb作为镜像构建的一部分。然后我们添加我们之前创建的custom-jwt.js
文件。
身份证的Composer默认目录是/home/composer/.composer
。在构建镜像之前,我们可以从home/composer/.composer
目录中复制现有的身份证。我们还需要更改文件权限,以便docker可以在没有EACCESS错误的情况下处理它们。
1 | cp -rp ~/.composer . |
我们现在可以构建Docker镜像了。
1 | docker build -t localhost/composer-rest-server . |
请注意,我们安装了loopback-connector-mongodb
作为镜像构建的一部分。这意味着我们将使用MongoDB作为存储我们经过身份验证的用户和凭据的首选数据库。因此,我们需要一个正在运行的MongoDB实例。
但是,此实例需要与当前运行的Hyperledger Fabric网络位于相同的Docker网络中。 当我们启动Hyperledger Fabric实例时,创建了一个名为composer_default
的网络。为了确认这一点,我们可以运行docker network ls
。
1 | docker network ls |
你可以看到我们有一个composer_default
网络。要检查使用此网络运行的容器,我们可以运行,并检查Container属性。
1 | docker network inspect composer_default |
你会注意到容器是当前正在运行的容器信息:
1 | "Containers": { |
在composer_default网络中运行mongodb容器。
1 | docker run -d --name mongo --network composer_default -p 27017:27017 mongo |
创建一个文件envvars.txt
。
1 | COMPOSER_CARD=admin@tutorial-network |
CUSTOM_PROVIDERS
环境变量指定我们使用jwt和自定义模块。
由于我们使用的是MongoDB,因此我们的CUSTOM_DATASOURCES
环境变量也指向此。
为了使这些变量成为实际的环境变量,我们运行:
1 | source envvars.txt |
然后我们可以在composer_default网络中运行Docker容器。
1 | docker run \ |
为确保composer rest server 成功运行,我们检查其日志。
1 | docker logs rest |
如果你看到最后一行在http://localhost:3000/explorer
浏览你的REST API,我们很好。
访问http://localhost:3000/explorer
并尝试在任何端点上执行GET将返回401 Unauthorized
。
验证Composer Rest服务器
要对Composer Rest server进行身份验证,我们需要执行以下操作:
- 使用作为承载token传递的有效jwt token调用路径
http://localhost:3000/auth/jwt/callback
。 - 从cookie中检索访问token,因为这是响应返回的方式。
- 使用检索到的token通过
http://localhost:3000/api/wallet/import
路由导入身份证。 - 调用其他端点。
我们将使用Postman进行此练习,因为它是将header传递给请求的直观方式之一,因此我们不会真正做到第二,因为cookie将在后续请求中传递。
但是,如果你有一个客户端使用composer-rest服务器,则需要从返回的access_token cookie中检索token。这是一些用于检索token的示例代码,这是来自Hyperledger结构。我们可能会在另一篇文章中看到建立这样的客户端。
我根据上述加密gSi4WmttWuvy2ewoTGooigPwSDoxwZOy
生成了一个JWT token,声称如下:"timestamp":time.Now().UnixNano(),"username": username
。语法适用于Golang,但声明是当前时间戳,用户名是gangachris
。结果token就是这个。
1 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE1MjcxNjI1MDQ3NDI1NjUwODcsInVzZXJuYW1lIjoiZ2FuZ2FjaHJpcyJ9.WyARsOhMSDVRjUpd-rPBI1A8-Vpz7pDS6rICXKN8W3U |
请注意,此token不安全,因为它没有足够的声明和到期日。这仅用于演示目的。
接下来,我们做一个GET请求http://localhost:3000/auth/jwt/callback
后结果eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE1MjcxNjI1MDQ3NDI1NjUwODcsInVzZXJuYW1lIjoiZ2FuZ2FjaHJpcyJ9.WyARsOhMSDVRjUpd-rPBI1A8-Vpz7pDS6rICXKN8W3U
作为header。可以在Postman的Authorization选项卡中轻松添加此header。
请注意,我们收到了三个cookie的回复。connect.sid
,access_token
和userId
。如果你熟悉JavaScript,现在可以看到我之前共享的代码如何用于为后续请求提取access_token。
如果现在删除授权标头并调用http://localhost:3000/api/SampleAsset
,则不会收到401 Unauthorized
错误,但500 A business network card has not been specified
。
要导入card,我们向http://localhost:3000/api/Wallet/import
发出POST请求,并附上我们在创建参与者时生成的身份卡和名称,在本例中为gangachris
。
请注意,我们会收到204 No Content
回复。
要确认card已成功导入,我们将调用http://localhost:3000/api/Wallet
。
我们收到一个包含钱包列表的回复,以及当前使用的默认值。
在此阶段,我们成功通过身份验证,并调用http://localhost:3000/api/SampleAsset
路由,没有任何错误。
注意事项
我们能够在调用http://localhost:3000/auth/jwt/callback
之后调用这些请求的唯一原因是因为Postman正在使用它在此请求中获得的cookie以用于后续请求。
当你拥有自定义客户端时,这将不起作用。在这种情况下,你必须通过类似这样的代码检索访问token,然后使用header或查询参数进行后续调用,如下所示。
1 | curl -v http://localhost:3000/api/system/ping?access_token=xxxxx |
身份验证后的第一个请求必须是对http://localhost:3000/api/Wallet/import
的POST,并传递身份验证卡和名称。调用http://localhost:3000/api/Wallet
以检查默认钱包并确保它是正确的钱包是有意义的。
通过身份验证后,你可以通过发布到参与者路线来创建其他参与者。在这种情况下,它的POST http://localhost:3000/api/SampleAprticipant
。然后为了向他们发一个身份,你必须向http://localhost:3000/api//system/identities/issue
发出另一个帖子请求,带有相关参数,这将返回二进制响应,你必须将其保存到.card
文件中。
为避免使用Postman,你可以更改我们使用passportJwt.ExtractJwt.fromUrlQueryParameter(“token”)
创建的custom-jwt.js文件中的passport-jwt检索jwt token的方式;
1 | function CustomJwtStrategy(options, verify) { |
一旦更改,你可以访问http://localhost:3000/auth/jwt/callback?query=<token>
,然后你将返回swagger页面。
结论
Hyperledger Composer是一个很好的资源,可以帮助你启动并运行Hyperledger Fabric区块链。
你可能拥有一个现有系统,并且你希望集成Hyperledger Fabric,本文简要介绍了实现此目标的方法之一。
希望尽快学习的请访问Fabric区块链开发详解,本课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、通道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、nodejs链码与应用开发的操作实践,是Nodejs工程师学习Fabric区块链开发的最佳选择。
======================================================================
分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:
- EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。
- java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
- python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
- php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。
- 以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。
- 以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
- ERC721以太坊通证实战,课程以一个数字艺术品创作与分享DApp的实战开发为主线,深入讲解以太坊非同质化通证的概念、标准与开发方案。内容包含ERC-721标准的自主实现,讲解OpenZeppelin合约代码库二次开发,实战项目采用Truffle,IPFS,实现了通证以及去中心化的通证交易所。
- C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。
- java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。
- php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。
- tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。
汇智网原创翻译,转载请标明出处。这里是原文Hyperledger Composer Rest服务器的Passport-JWT身份验证