Reputation: 2069
First of all, I am very new to hyperledger and probably I am thinking wrong at some place.
Right now, I am working on an application that I am doing with Hyperledger Fabric, Hyperledger Composer and hyperledger-rest-server.
Now I read a bit about the authentication process but I got stuck at one point.
Before I get to my questions, I tell you a bit more about what I want:
I want to create a frontend application with angular where the user can log in with his username/password.
What I read is that I can use Passport.js for hyperledger-rest-server authentication. But what I understood, is that this is for authentication with third parties like twitter, facebook etc.
My Questions:
Upvotes: 0
Views: 335
Reputation: 1587
Yes this is one such option and completely feasible. You can use passportjs
with composer-rest-server
and link a username
to a unique composer business card
. This way when the user logs in, it gets a token from the server. Every subsequent API call must have the token, based on this the rest server will use the required composer card
You would first need to follow this and setup your server using composer-rest-server -c ADMIN_CARD_NAME
. You will then need to activate authentication for the server. Go to http://0.0.0.0:3000/explorer to view the APIs including those for authentication.
Based on the authentication method you would need to install the required package. This tutorial is a great place to start. Using the wallet import
endpoint, the admin can map a Facebook account or a username to a particular composer card
.
Now my honest opinion is, composer-rest-server
is not suitable for a pilot/ production rollout. I have used this and ultimately decided to handle my own APIs and authentication.
async function createParticipant() {
const businessNetworkConnection = new BusinessNetworkConnection();
await businessNetworkConnection.connect(adminCardName);
let registry= await businessNetworkConnection.getParticipantRegistry(`${BASE_NS}.SampleUser`);
const factory = businessNetworkConnection.getBusinessNetwork().getFactory();
let user= factory.newResource(BASE_NS, 'SampleUser', 'username123');
await businessNetworkConnection.save(user);
// User is registered, time to import an identity
let creds = await businessNetworkConnection.issueIdentity(`${BASE_NS}.SampleUser#username123`, 'username123);
const adminConnection = new AdminConnection();
await adminConnection.connect(adminCardName);
const card = new IdCard({
userName: creds.userID,
version: 1,
enrollmentSecret: creds.userSecret,
businessNetwork: businessName
}, connectionProfile);
await adminConnection.importCard(`username123@my-network`, card);
await adminConnection.disconnect();
await businessNetworkConnection.disconnect();
}
composer card
. For this example I have used mongoDB. The schema would be something like thislet newUser = new userSchema({
username: 'Alice,
password: 'topSecretPassword,
emailId: '[email protected]',
participantId: 'username123,
composerCard: `username123@my-network`
});
jsonwebtoken
that she must use in all subsequent API calls.const jwt = require('jsonwebtoken');
app.post('/login', auth());
async function auth(req, res, next) {
let username = req.body.username;
let password = req.body.password;
// User whatever authentication method you want here and return a jwt
// In my project I created a new token db and kept a mapping
const authToken = jwt.sign(tokenSeed, jwtSecret, { });
const newToken = new tokenSchema({
authToken: authToken,
username: req.body.username
});
await newToken.save();
res.send({ authToken: authToken, username: username });
}
composer card
to use for the transactionsconst chooseCard = async (req, res, next) => {
// Retrieve the token from the DB
let token = await tokenSchema.findOne({ authToken: req.headers['x-access-token'] });
// Get the user information
let user = await userSchema.findOne({ username: token.username });
let card = user.composerCard;
req.composerCardToUse = card;
next();
};
const someFancyTx = async (req, res, next) => {
let card = req.composerCardToUse;
await businessNetworkConnection.connect(card);
// And the transactions submitted with this instance will use the required card
}
app.post('/sendMoney', chooseCard, somefancyTx);
NOTE: I have skipped a few validation steps (check authenticity of jwt, user session) and skipped some of the boilerplate code that would make this answer unnecessarily long. I have run a pilot and a PoC successfully using this same system.
Upvotes: 1