Skip to content

Commit

Permalink
example: add csrf-token to jwt example (#1013)
Browse files Browse the repository at this point in the history
* add csrf-token to jwt example

* grovel for the linter

* use default remote-docker version
  • Loading branch information
glooms authored Sep 17, 2024
1 parent f8c1d82 commit 932f330
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 44 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
<<: *defaults
steps:
- setup_remote_docker:
version: 19.03.13
version: default
- attach_workspace:
at: ~/enigma.js
- run:
Expand Down
105 changes: 62 additions & 43 deletions examples/authentication/sense-using-jwt/jwt.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,55 +4,74 @@ const path = require('path');
const fs = require('fs');
const jwt = require('jsonwebtoken');

const schema = require('enigma.js/schemas/12.20.0.json');
const schema = require('enigma.js/schemas/12.2027.0.json');

// Your Sense Enterprise installation hostname:
const senseHost = 'localhost';
const getCsrfToken = async (host, auth) => {
try {
const res = await fetch(`${host}/qps/csrftoken`, {
headers: {
Authorization: `Bearer ${auth}`,
},
});
return res.headers.get('QLIK_CSRF_TOKEN');
} catch (err) {
console.log('Failed to fetch csrf-token', err);
}
return '';
};

// Your configured virtual proxy prefix for JWT authentication:
const proxyPrefix = 'jwt';
(async () => {
// Your Sense Enterprise installation hostname:
const senseHost = 'localhost';

// The Sense Enterprise-configured user directory for the user you want to identify
// as:
const userDirectory = 'your-sense-user-directory';
// Your configured virtual proxy prefix for JWT authentication:
const proxyPrefix = 'jwt';

// The user to use when creating the session:
const userId = 'your-sense-user';
// The Sense Enterprise-configured user directory for the user you want to identify
// as:
const userDirectory = 'your-sense-user-directory';

// The Sense Enterprise-configured JWT structure. Change the attributes to match
// your configuration:
const token = {
directory: userDirectory,
user: userId,
};
// The user to use when creating the session:
const userId = 'your-sense-user';

// Path to the private key used for JWT signing:
const privateKeyPath = './keys/private.key';
const key = fs.readFileSync(path.resolve(__dirname, privateKeyPath));

// Sign the token using the RS256 algorithm:
const signedToken = jwt.sign(token, key, { algorithm: 'RS256' });

const config = {
schema,
url: `wss://${senseHost}/${proxyPrefix}/app/engineData`,
// Notice how the signed JWT is passed in the 'Authorization' header using the
// 'Bearer' schema:
createSocket: (url) => new WebSocket(url, {
headers: { Authorization: `Bearer ${signedToken}` },
}),
};
// The Sense Enterprise-configured JWT structure. Change the attributes to match
// your configuration:
const token = {
directory: userDirectory,
user: userId,
};

// Path to the private key used for JWT signing:
const privateKeyPath = './keys/private.key';
const key = fs.readFileSync(path.resolve(__dirname, privateKeyPath));

// Sign the token using the RS256 algorithm:
const signedToken = jwt.sign(token, key, { algorithm: 'RS256' });

const csrfToken = await getCsrfToken(`https://${senseHost}/${proxyPrefix}`, signedToken);
const csrfQuery = csrfToken ? `&qlik-csrf-token=${csrfToken}` : '';

const config = {
schema,
url: `wss://${senseHost}/${proxyPrefix}/app/engineData${csrfQuery}`,
// Notice how the signed JWT is passed in the 'Authorization' header using the
// 'Bearer' schema:
createSocket: (url) => new WebSocket(url, {
headers: { Authorization: `Bearer ${signedToken}` },
}),
};

const session = enigma.create(config);
const session = enigma.create(config);

session.open().then((global) => {
console.log('Session was opened successfully');
return global.getDocList().then((list) => {
const apps = list.map((app) => `${app.qDocId} (${app.qTitle || 'No title'})`).join(', ');
console.log(`Apps on this Engine that the configured user can open: ${apps}`);
session.close();
session.open().then((global) => {
console.log('Session was opened successfully');
return global.getDocList().then((list) => {
const apps = list.map((app) => `${app.qDocId} (${app.qTitle || 'No title'})`).join(', ');
console.log(`Apps on this Engine that the configured user can open: ${apps}`);
session.close();
});
}).catch((error) => {
console.log('Failed to open session and/or retrieve the app list:', error);
process.exit(1);
});
}).catch((error) => {
console.log('Failed to open session and/or retrieve the app list:', error);
process.exit(1);
});
})();

0 comments on commit 932f330

Please sign in to comment.