注册用户账号

在上一节中注册管理员了,接下来我们需要使用这个管理员账号来注册用户,因此本节我们重点来讲解下注册用户的代码

打开$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:用户账号名为appUser
role:角色为客户端

使用此密钥将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,否则追究其法律责任

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章