註冊用戶賬號

在上一節中註冊管理員了,接下來我們需要使用這個管理員賬號來註冊用戶,因此本節我們重點來講解下注冊用戶的代碼

打開$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,否則追究其法律責任

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