Add verify option for nonce validation (#540)

* Add verify option for nonce validation

* Update README.md

Co-Authored-By: kazuki229 <[email protected]>

* Refactor option-nonce test

* Add nonce option validation
This commit is contained in:
kazuki229
2018-11-14 11:02:59 +01:00
committed by Eduardo Diaz
parent 1ab3963eef
commit c7e16cb5d5
3 changed files with 68 additions and 0 deletions
+1
View File
@@ -146,6 +146,7 @@ As mentioned in [this comment](https://github.com/auth0/node-jsonwebtoken/issues
* `maxAge`: the maximum allowed age for tokens to still be valid. It is expressed in seconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms).
> Eg: `1000`, `"2 days"`, `"10h"`, `"7d"`. A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default (`"120"` is equal to `"120ms"`).
* `clockTimestamp`: the time in seconds that should be used as the current time for all necessary comparisons.
* `nonce`: if you want to check `nonce` claim, provide a string value here. It is used on Open ID for the ID Tokens. ([Open ID implementation notes](https://openid.net/specs/openid-connect-core-1_0.html#NonceNotes))
```js
+57
View File
@@ -0,0 +1,57 @@
'use strict';
const jwt = require('../');
const expect = require('chai').expect;
const util = require('util');
const testUtils = require('./test-utils')
describe('nonce option', function () {
let token;
beforeEach(function () {
token = jwt.sign({ nonce: 'abcde' }, undefined, { algorithm: 'none' });
});
[
{
description: 'should work with a string',
nonce: 'abcde',
},
].forEach((testCase) => {
it(testCase.description, function (done) {
testUtils.verifyJWTHelper(token, undefined, { nonce: testCase.nonce }, (err, decoded) => {
testUtils.asyncCheck(done, () => {
expect(err).to.be.null;
expect(decoded).to.have.property('nonce', 'abcde');
});
});
});
});
[
true,
false,
null,
-1,
0,
1,
-1.1,
1.1,
-Infinity,
Infinity,
NaN,
'',
' ',
[],
['foo'],
{},
{ foo: 'bar' },
].forEach((nonce) => {
it(`should error with value ${util.inspect(nonce)}`, function (done) {
testUtils.verifyJWTHelper(token, undefined, { nonce }, (err) => {
testUtils.asyncCheck(done, () => {
expect(err).to.be.instanceOf(jwt.JsonWebTokenError);
expect(err).to.have.property('message', 'nonce must be a non-empty string')
});
});
});
});
});
+10
View File
@@ -33,6 +33,10 @@ module.exports = function (jwtString, secretOrPublicKey, options, callback) {
return done(new JsonWebTokenError('clockTimestamp must be a number'));
}
if (options.nonce !== undefined && (typeof options.nonce !== 'string' || options.nonce.trim() === '')) {
return done(new JsonWebTokenError('nonce must be a non-empty string'));
}
var clockTimestamp = options.clockTimestamp || Math.floor(Date.now() / 1000);
if (!jwtString){
@@ -179,6 +183,12 @@ module.exports = function (jwtString, secretOrPublicKey, options, callback) {
}
}
if (options.nonce) {
if (payload.nonce !== options.nonce) {
return done(new JsonWebTokenError('jwt nonce invalid. expected: ' + options.nonce));
}
}
if (options.maxAge) {
if (typeof payload.iat !== 'number') {
return done(new JsonWebTokenError('iat required when maxAge is specified'));