Skip to content
This repository was archived by the owner on Oct 18, 2024. It is now read-only.

Commit a1cdfa7

Browse files
authored
Merge pull request #7 from solepano/addJwtOptions
pass options to jwt.verify to be able to verify audience and issuer. Also fix example.
2 parents 8f17741 + 0975c05 commit a1cdfa7

5 files changed

Lines changed: 499 additions & 17 deletions

File tree

‎README.md‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ JSON Web Token authentication requires verifying a signed token. The `'jwt'` sch
1515
- `credentials` - a credentials object passed back to the application in `request.auth.credentials`. Typically, `credentials` are only
1616
included when `isValid` is `true`, but there are cases when the application needs to know who tried to authenticate even when it fails
1717
(e.g. with authentication mode `'try'`).
18+
- `audience` (optional): string or array of strings of valid values for the `aud` field.
19+
- `issuer` (optional): string or array of strings of valid values for the `iss` field.
20+
- `algorithms` (optional): List of strings with the names of the allowed algorithms. For instance, `["HS256", "RS256"]`.
21+
- `subject` (optional): string of valid values for the `sub` field
1822

1923
See the example folder for an executable example.
2024

@@ -45,7 +49,7 @@ var privateKey = 'BbZJjyoXAdr8BUZuiKKARWimKfrSmQ6fv8kZ7OFfc';
4549
var token = jwt.sign({ accountId: 123 }, privateKey);
4650

4751

48-
var validate = function (decodedToken, callback) {
52+
var validate = function (decodedToken, extraInfo, callback) {
4953

5054
var error,
5155
credentials = accounts[decodedToken.accountId] || {};
@@ -90,3 +94,16 @@ server.register(require('hapi-auth-jwt'), function (error) {
9094
server.start();
9195

9296
```
97+
98+
You can specify audience, issuer, algorithms and/or subject as well:
99+
100+
```javascript
101+
server.auth.strategy('token', 'jwt', {
102+
key: privateKey,
103+
validateFunc: validate,
104+
audience: 'http://myapi/protected',
105+
issuer: 'http://issuer',
106+
algorithms: ['RS256'],
107+
subject: 'myRequiredSubject'
108+
});
109+
```

‎example/index.js‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,17 @@ var token = jwt.sign({ accountId: 123 }, privateKey);
1919

2020
// use this token to build your web request. You'll need to add it to the headers as 'authorization'. And you will need to prefix it with 'Bearer '
2121
console.log('token: ' + token);
22+
console.log();
23+
console.log('=== Sample call to secure endpoint: ===');
24+
console.log("curl 'http://localhost:8080/tokenRequired' -H 'Content-Type:application/json' -H 'Authorization: Bearer " + token + "'");
25+
console.log();
26+
console.log('=== Sample call to public endpoint: ===');
27+
console.log("curl 'http://localhost:8080/noTokenRequired' -H 'Content-Type:application/json'");
2228

23-
var validate = function (decodedToken, callback) {
29+
var validate = function (decodedToken, extraInfo, callback) {
2430

25-
console.log(decodedToken); // should be {accountId : 123}.
31+
console.log('decodedToken',decodedToken); // should be {accountId : 123}.
32+
console.log('extraInfo',extraInfo);
2633

2734
if (decodedToken) {
2835
console.log(decodedToken.accountId.toString());

‎lib/index.js‎

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,18 @@
33
var Boom = require('boom');
44
var Hoek = require('hoek');
55
var jwt = require('jsonwebtoken');
6+
var Joi = require('joi');
67

8+
var optionsSchema = Joi.object().keys({
9+
key: Joi.alternatives().try(Joi.binary(),Joi.func()).required(),
10+
validateFunc: Joi.func(),
11+
algorithms: Joi.array().items(Joi.string()),
12+
audience: Joi.alternatives().try(Joi.string(),Joi.array().items(Joi.string())),
13+
issuer: Joi.alternatives().try(Joi.string(),Joi.array().items(Joi.string())),
14+
subject: Joi.string()
15+
}).label('jwt auth strategy options');
716

817
// Declare internals
9-
1018
var internals = {};
1119

1220

@@ -26,8 +34,11 @@ function isFunction(functionToCheck) {
2634

2735
internals.implementation = function (server, options) {
2836

29-
Hoek.assert(options, 'Missing jwt auth strategy options');
30-
Hoek.assert(options.key, 'Missing required private key in configuration');
37+
var validationResult = Joi.validate(options, optionsSchema);
38+
39+
if (validationResult.error){
40+
throw new Error(validationResult.error.message);
41+
}
3142

3243
var settings = Hoek.clone(options);
3344

@@ -62,13 +73,11 @@ internals.implementation = function (server, options) {
6273

6374
getKey(request, token, function(err, key, extraInfo){
6475
if (err) { return reply(Boom.wrap(err)); }
65-
6676
// handle err
67-
jwt.verify(token, key, function(err, decoded) {
68-
if(err && err.message === 'jwt expired') {
69-
return reply(Boom.unauthorized('Expired token received for JSON Web Token validation', 'Bearer'));
70-
} else if (err) {
71-
return reply(Boom.unauthorized('Invalid signature received for JSON Web Token validation', 'Bearer'));
77+
jwt.verify(token, key, settings, function(err, decoded) {
78+
79+
if(err) {
80+
return reply(Boom.unauthorized( 'JSON Web Token validation failed: ' + err.message, 'Bearer'));
7281
}
7382

7483
if (!settings.validateFunc) {
@@ -102,5 +111,6 @@ internals.implementation = function (server, options) {
102111
}
103112
};
104113

105-
return scheme;
114+
return scheme;
115+
106116
};

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
"dependencies": {
1818
"boom": "2.x.x",
1919
"hoek": "2.x.x",
20+
"joi": "^10.0.1",
2021
"jsonwebtoken": "^5.4.1"
2122
},
2223
"devDependencies": {
23-
"boom": "2.x.x",
2424
"code": "1.x.x",
2525
"hapi": "11.x.x",
2626
"lab": "5.x.x",

0 commit comments

Comments
 (0)