This document provides instructions for generating MigratoryData JWT tokens with Node.js.
Signing algorithms
MigratoryData JWT Authorization add-on supports both symmetric and asymmetric signatures:
HMAC
This symmetric signature method uses a secret key for signing the JWT tokens by your backend. The same secret key must be used for verifying the JWT tokens by the JWT Authorization add-on. The signature algorithms supported by this method, automatically selected according to the length of the secret key, are as follows:
- HS256 (HMAC SHA256), requires a 32-byte secret - recommended for most use cases
- HS384 (HMAC SHA384), requires a 48-byte secret
- HS512 (HMAC SHA512), requires a 64-byte secret
For example, to generate a 32-byte HMAC secret key, you can use the following command:
openssl rand -base64 32
RSA
This asymmetric signature method uses a pair of public and private keys. The private key should be used by your backend for signing the JWT tokens. The public key should be used by the JWT Authorization add-on for verifying the JWT tokens. The signature algorithms supported by this method, automatically selected according to the length of the private key, are as follows:
- RS256 (RSA SHA256), requires a 2048-bit private key - recommended for most use cases
- RS384 (RSA SHA384), requires a 3072-bit private key
- RS512 (RSA SHA512), requires a 4096-bit private key
For example, to generate a 2048-bit RSA pair of keys, you can use the following commands. Generate a private key using this command:
openssl genrsa \
-out rsa-private-key.pem \
2048
Then, extract the public key from the private key as follows:
openssl rsa -in rsa-private-key.pem \
-pubout \
-outform PEM \
-out rsa-public-key.pem
rsa-public-key.pem
to the JWT Authorization add-on folder and configure its parameter
signature.rsa.publicKeyPath accordingly.
Node.js JWT tokens generator
You need to have installed Node.js and npm
.
- Create a Node.js project and add the dependencies
express
(for http requests) andjsonwebtoken
(for token generation) as follows:
npm init
npm install express
npm install jsonwebtoken@~8.5.1
- Create a javascript file
index.js
in the current project with the following content:
const express = require('express')
const jwt = require('jsonwebtoken')
const fs = require('fs')
const app = express()
const port = 8080
const subjectReg = new RegExp(/^\/([^\/]+\/)*([^\/]+|\*)$/);
const config = {
username: 'admin',
password: 'password',
key: 'He39zDQW7RdkOcxe3L9qvoSQ/ef40BG6Ro4hrHDjE+U=', /* HMAC */
//key: fs.readFileSync('rsa-private-key.pem'), /* RSA */
}
function generateToken(permissions, ttl, key) {
var token = jwt.sign({permissions: permissions}, Buffer.from(key, 'base64'), {expiresIn: ttl}); /* HMAC */
//var token = jwt.sign({permissions: permissions}, key, { algorithm: 'RS256', expiresIn: ttl }); /* RSA */
return token;
}
function isSubjectValid(subject) {
return subjectReg.test(subject);
}
app.use(express.json());
app.post('/token/generate', (req, res) => {
console.log(req.body);
if (req.body.username !== config.username || req.body.password !== config.password) {
res.status(400).json({response: 'Invalid username or password!'});
}
for (let permission in req.body.permissions) {
for (let subject of req.body.permissions[permission]) {
if (!isSubjectValid(subject)) {
res.status(400).json({response: `Error, invalid subject format for subject: ${subject}`});
return;
}
}
}
res.json({response: generateToken(req.body.permissions, req.body.ttlSeconds, config.key)});
})
app.listen(port, () => {
console.log(`JWT token generator is listening on port ${port}`)
})
- Run the JWT token generator
node index.js
- Generate JWT tokens with
publish
andsubscribe
permissions for subjects
For example, run the following command to generate a JWT token valid one hour (i.e. 3600 seconds) with the following permissions:
- the client is authorized to subscribe to the subject
/sensor/temp
- the client is authorized to publish to the subject
/sensor/notification
- the client is authorized to both subscribe to and publish on the subject
/server/status
curl -X POST http://127.0.0.1:8080/token/generate \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"password", "ttlSeconds": 3600, "permissions": { "sub": ["/sensor/temp"], "pub": ["/sensor/notification"], "all" :["/server/status"]}}'