Added nbf support

This commit is contained in:
TAT
2015-06-26 22:46:14 +02:00
parent ab76ec5bc5
commit f26ba4e2fa
4 changed files with 71 additions and 1 deletions
+4 -1
View File
@@ -26,6 +26,7 @@ encoded private key for RSA and ECDSA.
* `algorithm` (default: `HS256`)
* `expiresInMinutes` or `expiresInSeconds`
* `notBeforeMinutes` or `notBeforeSeconds`
* `audience`
* `subject`
* `issuer`
@@ -37,7 +38,7 @@ encoded private key for RSA and ECDSA.
If `payload` is not a buffer or a string, it will be coerced into a string
using `JSON.stringify`.
If any `expiresInMinutes`, `audience`, `subject`, `issuer`, `jwtid`, `subject` are not provided, there is no default. The jwt generated won't include those properties in the payload.
If any `expiresInMinutes`, `notBeforeMinutes`, `audience`, `subject`, `issuer`, `jwtid`, `subject` are not provided, there is no default. The jwt generated won't include those properties in the payload.
Additional headers can be provided via the `headers` object.
@@ -60,6 +61,7 @@ var token = jwt.sign({ foo: 'bar' }, cert, { algorithm: 'RS256'});
`options`:
* `ignoreExpiration`
* `ignoreNotBefore`
* `audience`
* `issuer`
* `jwtid`
@@ -81,6 +83,7 @@ encoded public key for RSA and ECDSA.
* `audience`: if you want to check audience (`aud`), provide a value here
* `issuer`: if you want to check issuer (`iss`), provide a value here
* `ignoreExpiration`: if `true` do not validate the expiration of the token.
* `ignoreNotBefore`: if `true` do not validate the not before of the token.
* `jwtid`: if you want to check JWT ID (`jti`), provide a value here
* `subject`: if you want to check subject (`sub`), provide a value here
+17
View File
@@ -1,6 +1,7 @@
var jws = require('jws');
var JsonWebTokenError = module.exports.JsonWebTokenError = require('./lib/JsonWebTokenError');
var NotBeforeError = module.exports.NotBeforeError = require('./lib/NotBeforeError');
var TokenExpiredError = module.exports.TokenExpiredError = require('./lib/TokenExpiredError');
module.exports.decode = function (jwt, options) {
@@ -53,6 +54,14 @@ module.exports.sign = function(payload, secretOrPrivateKey, options) {
if (!options.noTimestamp) {
payload.iat = payload.iat || timestamp;
}
var notBeforeSeconds = options.notBeforeMinutes ?
options.notBeforeMinutes * 60 :
options.notBeforeSeconds;
if (notBeforeSeconds) {
payload.nbf = timestamp + notBeforeSeconds;
}
var expiresInSeconds = options.expiresInMinutes ?
options.expiresInMinutes * 60 :
@@ -167,6 +176,14 @@ module.exports.verify = function(jwtString, secretOrPublicKey, options, callback
} catch(err) {
return done(err);
}
if (typeof payload.nbf !== 'undefined' && !options.ignoreNotBefore) {
if (typeof payload.nbf !== 'number') {
return done(new JsonWebTokenError('invalid nbf value'));
}
if (payload.nbf >= Math.floor(Date.now() / 1000))
return done(new NotBeforeError('jwt not active', new Date(payload.nbf * 1000)));
}
if (typeof payload.exp !== 'undefined' && !options.ignoreExpiration) {
if (typeof payload.exp !== 'number') {
+13
View File
@@ -0,0 +1,13 @@
var JsonWebTokenError = require('./JsonWebTokenError');
var NotBeforeError = function (message, date) {
JsonWebTokenError.call(this, message);
this.name = 'NotBeforeError';
this.date = date;
};
NotBeforeError.prototype = Object.create(JsonWebTokenError.prototype);
NotBeforeError.prototype.constructor = NotBeforeError;
module.exports = NotBeforeError;
+37
View File
@@ -88,6 +88,43 @@ describe('RS256', function() {
});
});
describe('when signing a token with not before', function() {
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256', notBeforeMinutes: -10 });
it('should be valid expiration', function(done) {
jwt.verify(token, pub, function(err, decoded) {
assert.isNotNull(decoded);
assert.isNull(err);
done();
});
});
it('should be invalid', function(done) {
// not active token
token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256', notBeforeMinutes: 10 });
jwt.verify(token, pub, function(err, decoded) {
assert.isUndefined(decoded);
assert.isNotNull(err);
assert.equal(err.name, 'NotBeforeError');
assert.instanceOf(err.date, Date);
assert.instanceOf(err, jwt.NotBeforeError);
done();
});
});
it('should NOT be invalid', function(done) {
// not active token
token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256', notBeforeMinutes: 10 });
jwt.verify(token, pub, { ignoreNotBefore: true }, function(err, decoded) {
assert.ok(decoded.foo);
assert.equal('bar', decoded.foo);
done();
});
});
});
describe('when signing a token with audience', function() {
var token = jwt.sign({ foo: 'bar' }, priv, { algorithm: 'RS256', audience: 'urn:foo' });