Hyperledger Fabric Composer-Rest-Server如何设置用户名/密码验证?

时间:2019-02-20 13:50:16

标签: passport.js hyperledger-fabric hyperledger hyperledger-composer

首先,我对超级账本非常陌生,可能在某些地方我想错了。

现在,我正在使用Hyperledger Fabric,Hyperledger Composer和hyperledger-rest-server开发的应用程序上工作。

现在,我阅读了一些有关身份验证过程的信息,但我只停留在一点。

在我提出问题之前,我先告诉您一些我想要的东西:

我想创建一个带有角度的前端应用程序,以便用户可以使用其用户名/密码登录。

我读到的是可以使用Passport.js进行hyperledger-rest-server身份验证。但是我了解的是,这是为了与Twitter,Facebook等第三方进行身份验证。

我的问题:

  • 我的想法在这里正确吗?
  • 这可能吗?
  • 我该怎么办?
  • 用户是否还可以更改密码?
  • 使用Passport.js,管理员如何定义哪个帐户的Facebook帐户?我的意思是Hyperledger需要知道我的Facebook帐户属于Hyperledger Fabric帐户。

1 个答案:

答案 0 :(得分:0)

是的,这是一种这样的选择,并且完全可行。您可以将passportjscomposer-rest-server结合使用,并将username链接到唯一的composer business card。这样,当用户登录时,它将从服务器获取令牌。随后的每个API调用都必须具有令牌,基于此令牌,其余服务器将使用所需的composer card

您首先需要follow this并使用composer-rest-server -c ADMIN_CARD_NAME设置服务器。然后,您将需要为服务器激活身份验证。转到http://0.0.0.0:3000/explorer查看API,包括用于身份验证的API。

根据身份验证方法,您需要安装所需的软件包。 This tutorial是一个不错的起点。使用wallet import端点,管理员可以将Facebook帐户或用户名映射到特定的composer card

现在,我的诚实观点是,composer-rest-server不适合进行试生产。我使用了它,最终决定处理自己的API和身份验证。

  1. 创建参与者并导入身份
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();
}
  1. 使用您自己的数据库来存储用户的用户名和密码。将其映射到composer card。对于此示例,我使用了mongoDB。模式将是这样的
let newUser = new userSchema({
      username: 'Alice,
      password: 'topSecretPassword,
      emailId: 'foo@bar.com',
      participantId: 'username123,
      composerCard: `username123@my-network`
});
  1. 中间件(最重要)。因此,当爱丽丝登录时,系统将返回一个jsonwebtoken,她必须在所有后续API调用中使用它。
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 });
}
  1. 实际的API调用。因此,这基本上是一个中间件功能,用于检查令牌并确定用于交易的composer card
const 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);

注意:我已经跳过了一些验证步骤(检查jwt的真实性,用户会话),并跳过了一些样本代码,这些代码会使答案变得不必要地冗长。我已经使用同一系统成功运行了飞行员和PoC。