Skip to content

Commit 932f330

Browse files
authored
example: add csrf-token to jwt example (#1013)
* add csrf-token to jwt example * grovel for the linter * use default remote-docker version
1 parent f8c1d82 commit 932f330

File tree

2 files changed

+63
-44
lines changed

2 files changed

+63
-44
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ jobs:
6666
<<: *defaults
6767
steps:
6868
- setup_remote_docker:
69-
version: 19.03.13
69+
version: default
7070
- attach_workspace:
7171
at: ~/enigma.js
7272
- run:

examples/authentication/sense-using-jwt/jwt.js

Lines changed: 62 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,55 +4,74 @@ const path = require('path');
44
const fs = require('fs');
55
const jwt = require('jsonwebtoken');
66

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

9-
// Your Sense Enterprise installation hostname:
10-
const senseHost = 'localhost';
9+
const getCsrfToken = async (host, auth) => {
10+
try {
11+
const res = await fetch(`${host}/qps/csrftoken`, {
12+
headers: {
13+
Authorization: `Bearer ${auth}`,
14+
},
15+
});
16+
return res.headers.get('QLIK_CSRF_TOKEN');
17+
} catch (err) {
18+
console.log('Failed to fetch csrf-token', err);
19+
}
20+
return '';
21+
};
1122

12-
// Your configured virtual proxy prefix for JWT authentication:
13-
const proxyPrefix = 'jwt';
23+
(async () => {
24+
// Your Sense Enterprise installation hostname:
25+
const senseHost = 'localhost';
1426

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

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

22-
// The Sense Enterprise-configured JWT structure. Change the attributes to match
23-
// your configuration:
24-
const token = {
25-
directory: userDirectory,
26-
user: userId,
27-
};
34+
// The user to use when creating the session:
35+
const userId = 'your-sense-user';
2836

29-
// Path to the private key used for JWT signing:
30-
const privateKeyPath = './keys/private.key';
31-
const key = fs.readFileSync(path.resolve(__dirname, privateKeyPath));
32-
33-
// Sign the token using the RS256 algorithm:
34-
const signedToken = jwt.sign(token, key, { algorithm: 'RS256' });
35-
36-
const config = {
37-
schema,
38-
url: `wss://${senseHost}/${proxyPrefix}/app/engineData`,
39-
// Notice how the signed JWT is passed in the 'Authorization' header using the
40-
// 'Bearer' schema:
41-
createSocket: (url) => new WebSocket(url, {
42-
headers: { Authorization: `Bearer ${signedToken}` },
43-
}),
44-
};
37+
// The Sense Enterprise-configured JWT structure. Change the attributes to match
38+
// your configuration:
39+
const token = {
40+
directory: userDirectory,
41+
user: userId,
42+
};
43+
44+
// Path to the private key used for JWT signing:
45+
const privateKeyPath = './keys/private.key';
46+
const key = fs.readFileSync(path.resolve(__dirname, privateKeyPath));
47+
48+
// Sign the token using the RS256 algorithm:
49+
const signedToken = jwt.sign(token, key, { algorithm: 'RS256' });
50+
51+
const csrfToken = await getCsrfToken(`https://${senseHost}/${proxyPrefix}`, signedToken);
52+
const csrfQuery = csrfToken ? `&qlik-csrf-token=${csrfToken}` : '';
53+
54+
const config = {
55+
schema,
56+
url: `wss://${senseHost}/${proxyPrefix}/app/engineData${csrfQuery}`,
57+
// Notice how the signed JWT is passed in the 'Authorization' header using the
58+
// 'Bearer' schema:
59+
createSocket: (url) => new WebSocket(url, {
60+
headers: { Authorization: `Bearer ${signedToken}` },
61+
}),
62+
};
4563

46-
const session = enigma.create(config);
64+
const session = enigma.create(config);
4765

48-
session.open().then((global) => {
49-
console.log('Session was opened successfully');
50-
return global.getDocList().then((list) => {
51-
const apps = list.map((app) => `${app.qDocId} (${app.qTitle || 'No title'})`).join(', ');
52-
console.log(`Apps on this Engine that the configured user can open: ${apps}`);
53-
session.close();
66+
session.open().then((global) => {
67+
console.log('Session was opened successfully');
68+
return global.getDocList().then((list) => {
69+
const apps = list.map((app) => `${app.qDocId} (${app.qTitle || 'No title'})`).join(', ');
70+
console.log(`Apps on this Engine that the configured user can open: ${apps}`);
71+
session.close();
72+
});
73+
}).catch((error) => {
74+
console.log('Failed to open session and/or retrieve the app list:', error);
75+
process.exit(1);
5476
});
55-
}).catch((error) => {
56-
console.log('Failed to open session and/or retrieve the app list:', error);
57-
process.exit(1);
58-
});
77+
})();

0 commit comments

Comments
 (0)