User and session management

Before performing a network (channel) or chaincode operation, a user must establish an authenticated session. We will implement the /login API function as follows:

  1. Create a JWT token for a user with an expiration time of 60 seconds
  2. Register or log the user in
  3. If successful, return the token to the client

The server expects the name of a user and an organization name for registration or login to be provided as form data in the request body. An administrative user is simply identified by the admin username. The request body format is:

username=<username>&orgName=<orgname>[&password=<password>]

A password must be supplied, but only if the <username> is admin. In that case, the middleware will simply check whether the supplied password matches the one that was used to start the fabric-ca-server for the organization's MSP. As mentioned earlier in this chapter, our MSP administrator passwords were set to the default adminpw.

This is a naïve implementation, but as web application security is not the focus of this tutorial, this will suffice to show how a server and frontend can be implemented over a smart contract and middleware.

The code for JWT token creation and user registration/login can be found in the following express route configured in app.js:

app.post('/login', async function(req, res) { ... });

The reader may experiment with other mechanisms of session management, such as session cookies, in lieu of JWT tokens.

Our web application can now be tested. First, bring up the Fabric network using docker-compose (or trade.sh), as shown earlier in this chapter.

If you created fresh cryptographic keys and certificates for the organizations using cryptogen (or the trade.sh script), you MUST clear the temporary folder used by the middleware to save world state and user info, otherwise you may see errors if you try to register users with IDs that were used in a previous run of your application. For example: if the temporary folder is network/client-certs on your machine, you can simply run rm -rf client-certs from the network folder to clear the contents.

In a different terminal window, start the web application by running the following command:

node app.js

In a third terminal window, send a request to the web server using the curl command to create an ordinary user named Jim in the importerorg organization (this is the organization name specified in middleware/config.json):

curl -s -X POST http://localhost:4000/login -H "content-type: application/x-www-form-urlencoded" -d 'username=Jim&orgName=importerorg'

You should see an output like the following:

{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MjUwMDU4NTQsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6ImltcG9ydGVyb3JnIiwiaWF0IjoxNTI1MDAxNzE0fQ.yDX1PyKnpQAFC0mbo1uT1Vxgig0gXN9WNCwgp-1vj2g","success":true,"secret":"LNHaVEXHuwUf","message":"Registration successful"}

In the middleware, the function that gets executed here is getUserMember in clientUtils.js, which was discussed earlier in this chapter.

To create an administrative user in the same organization, run:

curl -s -X POST http://localhost:4000/login -H "content-type: application/x-www-form-urlencoded" -d 'username=admin&orgName=importerorg&password=adminpw'

You should see an output as follows (the admin user was already registered, so this ended up being a login call):

{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MjUwMDU4OTEsInVzZXJuYW1lIjoiYWRtaW4iLCJvcmdOYW1lIjoiaW1wb3J0ZXJvcmciLCJpYXQiOjE1MjUwMDE3NTF9.BYIEBO_MZzQa52_LW2AKVhLVag9OpSiZsI3cYHI9_oA","success":true,"message":"Login successful"}

In the middleware, the function that gets executed here is getMember in clientUtils.js.