Reputation: 25
I am developing an application over fabric 1.3 . I have built a network on multi-node setup, connected peers, instantiate chaincode and have my network up and ready for invocation and queries.
Now, I am thinking to make a log-in portal through which a user can register/enroll and perform invoke/queries. All my peers and orderer are on cloud, and am planning to provide this log-in feature using the Node SDK exposed on a cloud instance.
I went through the official doc: https://hyperledger-fabric-ca.readthedocs.io/en/latest/users-guide.html#registering-a-new-identity
I can see that we need fabric-ca component to register users and enroll them for queries. Upon enrollment, we get a cert files under ~/.hfc-key-store.
Now I want to understand how should I go ahead with my flow.
User signs up on network:
fabric_ca_client.register({enrollmentID: 'user1', affiliation: 'org1.department1'}, admin_user)
User log in with his secret:
fabric_ca_client.enroll({enrollmentID: 'user1', enrollmentSecret: secret});
}).then((enrollment) => {
console.log('Successfully enrolled member user "user1" ');
return fabric_client.createUser(
{username: 'user1',
mspid: 'Org1MSP',
cryptoContent: { privateKeyPEM: enrollment.key.toBytes(), signedCertPEM: enrollment.certificate }
});
}).then((user) => {
member_user = user;
return fabric_client.setUserContext(member_user);
Invoke/Query as user1:
var store_path = path.join(os.homedir(), '.hfc-key-store');
Fabric_Client.newDefaultKeyValueStore({ path: store_path
}).then((state_store) => {
// assign the store to the fabric client
fabric_client.setStateStore(state_store);
var crypto_suite = Fabric_Client.newCryptoSuite();
// use the same location for the state store (where the users' certificate are kept)
// and the crypto store (where the users' keys are kept)
var crypto_store = Fabric_Client.newCryptoKeyStore({path: store_path});
crypto_suite.setCryptoKeyStore(crypto_store);
fabric_client.setCryptoSuite(crypto_suite);
// get the enrolled user from persistence, this user will sign all requests
return fabric_client.getUserContext('user1', true);
}).then((user_from_store) => {
if (user_from_store && user_from_store.isEnrolled()) {
console.log('Successfully loaded user1 from persistence');
member_user = user_from_store;
} else {
throw new Error('Failed to get user1.... run registerUser.js');
}..
Now, what shall I do when a user logs out? delete the ~/.hfc-key-store certs? Since these certs are going to be stored on server side where Node script is running, so it doesn't make sense.
Also, is my flow correct or if there is any better way to accomplice my objective?
Upvotes: 1
Views: 2713
Reputation: 1821
Maybe a little late but maybe it can help someone. My approach is to do what you do in the login, in a register method where I return the certificate and the private key, then on login the user needs to provide both the certificate and the private keys generated (and also the certificate and the private key for the TLS connection), and with this information I recreate de Identity and store it in a MemoryWallet, and with this MemoryWallet now, I can create the gateway and connect to the blockchain.
It would be something like this
const identity = X509WalletMixin.createIdentity(mspId, certificate, privateKey);
const identityTLS = X509WalletMixin.createIdentity(mspId, certificateTLS, privateKeyTLS);
const wallet = new InMemoryWallet();
await wallet.import(userId, identity);
await wallet.import(userId + '-tls', identityTLS);
const gateway = new Gateway();
await gateway.connect(ccpPath, { wallet, identity: userId, discovery: { enabled: true, asLocalhost: false } });
const client = gateway.getClient();
const userTlsCert = await wallet.export(userId + '-tls') as any;
client.setTlsClientCertAndKey(userTlsCert.certificate, userTlsCert.privateKey);
Hope it helps
Upvotes: 0
Reputation: 166
When an identity (certs and keys) is issued by CA then it should be persisted for that particular user for future interactions (either by saving in client wallet or other methods) so if you delete it then there will be re-enroll process on each log in and it will slow it down too.
To resolve it - 1. Create separate logic like JWT token for log in and session management. 2. Save the keys and certs on server directory (not the best way but will work for now later) Let me know if it satisfies your query.
Upvotes: 0
Reputation: 491
I had a similar login implementation that I had to do, As you said I did create certificates for each registered user as well as stored the basic user information in MongoDB.
The flow that I went with is that once the user is registered the user certification is created as well as his login credentials such as username and password are stored in MongoDB.
When the user tries to login back, I would check the MongoDB as well as the certification to see if the user has already registered, once logged in the user would then be in possession of an auth token which he then can use to interact with the fabric-client.
Upvotes: 0