在上一节中注册管理员了,接下来我们需要使用这个管理员账号来注册用户,因此本节我们重点来讲解下注册用户的代码
打开$GOPATH/src/github.com/hyperledger/fabric-samples/fabcar/javascript/registerUser.js
文件,我们来看看代码。
首先下面部分代码同admin一样,不在详述。
'use strict';
const { Wallets } = require('fabric-network');
const FabricCAServices = require('fabric-ca-client');
const fs = require('fs');
const path = require('path');
async function main() {
try {
// 业务内容部分
} catch (error) {
console.error(`Failed to register user "appUser": ${error}`);
process.exit(1);
}
}
main();
我们重点看看业务内容部分
第一部分:加载test-network网络中组织1的的连接配置信息
同上一节一样,它获取到connection-org1.json的参数并转为json格式
const ccpPath = path.resolve(__dirname, '..', '..', 'test-network', 'organizations', 'peerOrganizations', 'org1.example.com', 'connection-org1.json');
const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
第二部分:创建一个新的CA客户端以与CA服务进行交互
从connection-org1.json
文件中获取组织1中的ca服务网址,它的值为:https://localhost:7054
const caURL = ccp.certificateAuthorities['ca.org1.example.com'].url;
实例化Fabric-CA证书服务
const ca = new FabricCAServices(caURL);
第三部分:创建一个新的基于文件系统的钱包来管理身份
同上一节,先获取到钱包的目录路径并实例化一个钱包对象
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = await Wallets.newFileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
第四部分:查看我们是否已经注册了用户用户
判断wallet目录下是否已经存在appUser.id这个文件,存在就表示这个用户已经注册过
const userIdentity = await wallet.get('appUser');
if (userIdentity) {
console.log('An identity for the user "appUser" already exists in the wallet');
return;
}
由此我们知道,注册用户也只需要一次,后面不再需要重复注册,如果要重新注册,需要先删除appUser.id这个文件才行。
第五部分:查看我们是否已经注册了管理员用户
因为用户账号需要用管理员来注册,因此要先进行管理员注册再能执行用户注册,如果管理员没有注册则要回到上一节先注册管理员。
const adminIdentity = await wallet.get('admin');
if (!adminIdentity) {
console.log('An identity for the admin user "admin" does not exist in the wallet');
console.log('Run the enrollAdmin.js application before retrying');
return;
}
第六部分:生成用户对象以使用CA进行身份验证
通过管理员的证书类型(X.509)来获取钱包的证书对象
const provider = wallet.getProviderRegistry().getProvider(adminIdentity.type);
获取管理员账号信息
const adminUser = await provider.getUserContext(adminIdentity, 'admin');
第七部分:注册用户并把用户身份信息导入到钱包中
管理员使用下面的信息将appUser用户注册到CA中,CA返回一个密钥
const secret = await ca.register({
affiliation: 'org1.department1',
enrollmentID: 'appUser',
role: 'client'
}, adminUser);
affiliation
:用户归属组织1的部门1下enrollmentID
:用户账号名为appUserrole
:角色为客户端
使用此密钥将appUser登记到CA中
const enrollment = await ca.enroll({
enrollmentID: 'appUser',
enrollmentSecret: secret
});
组装appUser的签名密钥和证书
const x509Identity = {
credentials: {
certificate: enrollment.certificate,
privateKey: enrollment.key.toBytes(),
},
mspId: 'Org1MSP',
type: 'X.509',
};
把用户身份信息存储到钱包中,也就是钱包目录下的appUser.id文件中,以后将用于执行链码交互使用,如查询和调用
await wallet.put('appUser', x509Identity);
console.log('Successfully registered and enrolled admin user "appUser" and imported it into the wallet');
总结一下
注册管理与注册用户的代码对比
我们可以看到以下逻辑
管理员只需要一步登记(enroll)就可以,而新用户先注册(register)再登记。为什么新用户注册需要这二步来呢?
这是因为这两个步骤应该由不同的组织方完成:
-
注册由第三方服务商(admin)完成,得到一个密钥(secret);
-
第三方服务商把密钥给到用户;
-
用户拿到密钥后自己完成登记,从而得到签名key和cert(即代码中的enrollment.key和enrollment.certificate)。
-
这就只有用户自己接收签名密钥,不会经过第三方服务商,因此即使第三方服务商不知道用户的签名密钥,从而保存了消息的保密性和安全性。
本文由小韦云原创,转载请注明出处:https://www.bctos.cn/doc/4/1833,否则追究其法律责任