mirror of
https://github.com/hanzoai/node-jsonwebtoken.git
synced 2026-09-24 17:00:48 +00:00
Merge branch 'max-age' of https://github.com/jden/node-jsonwebtoken into jden-max-age
This commit is contained in:
@@ -4,7 +4,7 @@ var JWT = module.exports;
|
||||
|
||||
var JsonWebTokenError = JWT.JsonWebTokenError = require('./lib/JsonWebTokenError');
|
||||
var TokenExpiredError = JWT.TokenExpiredError = require('./lib/TokenExpiredError');
|
||||
|
||||
var ms = require('ms')
|
||||
|
||||
JWT.decode = function (jwt, options) {
|
||||
options = options || {};
|
||||
@@ -202,5 +202,15 @@ JWT.verify = function(jwtString, secretOrPublicKey, options, callback) {
|
||||
return done(new JsonWebTokenError('jwt issuer invalid. expected: ' + options.issuer));
|
||||
}
|
||||
|
||||
if (options.maxAge) {
|
||||
var maxAge = ms(options.maxAge);
|
||||
if (typeof payload.iat !== 'number') {
|
||||
return done(new JsonWebTokenError('iat required when maxAge is specified'));
|
||||
}
|
||||
if (Date.now() - (payload.iat * 1000) > maxAge) {
|
||||
return done(new TokenExpiredError('maxAge exceeded', new Date(payload.iat * 1000 + maxAge)));
|
||||
}
|
||||
}
|
||||
|
||||
return done(null, payload);
|
||||
};
|
||||
|
||||
+4
-2
@@ -19,12 +19,14 @@
|
||||
"url": "https://github.com/auth0/node-jsonwebtoken/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"jws": "^3.0.0"
|
||||
"jws": "^3.0.0",
|
||||
"ms": "^0.7.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"atob": "^1.1.2",
|
||||
"chai": "^1.10.0",
|
||||
"mocha": "^2.1.0"
|
||||
"mocha": "^2.1.0",
|
||||
"sinon": "^1.15.4"
|
||||
},
|
||||
"engines": {
|
||||
"npm": ">=1.4.28"
|
||||
|
||||
+105
-1
@@ -2,6 +2,7 @@ var jwt = require('../index');
|
||||
var jws = require('jws');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var sinon = require('sinon');
|
||||
|
||||
var assert = require('chai').assert;
|
||||
|
||||
@@ -9,7 +10,7 @@ describe('verify', function() {
|
||||
var pub = fs.readFileSync(path.join(__dirname, 'pub.pem'));
|
||||
var priv = fs.readFileSync(path.join(__dirname, 'priv.pem'));
|
||||
|
||||
it('should first assume JSON claim set', function () {
|
||||
it('should first assume JSON claim set', function (done) {
|
||||
var header = { alg: 'RS256' };
|
||||
var payload = { iat: Math.floor(Date.now() / 1000 ) };
|
||||
|
||||
@@ -23,6 +24,109 @@ describe('verify', function() {
|
||||
jwt.verify(signed, pub, {typ: 'JWT'}, function(err, p) {
|
||||
assert.isNull(err);
|
||||
assert.deepEqual(p, payload);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('expiration', function () {
|
||||
// { foo: 'bar', iat: 1437018582, exp: 1437018583 }
|
||||
var token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIiLCJpYXQiOjE0MzcwMTg1ODIsImV4cCI6MTQzNzAxODU4M30.NmMv7sXjM1dW0eALNXud8LoXknZ0mH14GtnFclwJv0s';
|
||||
var key = 'key';
|
||||
|
||||
var clock;
|
||||
afterEach(function () {
|
||||
try { clock.restore(); } catch (e) {}
|
||||
});
|
||||
|
||||
it('should error on expired token', function (done) {
|
||||
clock = sinon.useFakeTimers(1437018650000);
|
||||
var options = {algorithms: ['HS256']};
|
||||
|
||||
jwt.verify(token, key, options, function (err, p) {
|
||||
assert.equal(err.name, 'TokenExpiredError');
|
||||
assert.equal(err.message, 'jwt expired');
|
||||
assert.equal(err.expiredAt.constructor.name, 'Date');
|
||||
assert.equal(Number(err.expiredAt), 1437018583000);
|
||||
assert.isUndefined(p);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not error on unexpired token', function (done) {
|
||||
clock = sinon.useFakeTimers(1437018582000);
|
||||
var options = {algorithms: ['HS256']}
|
||||
|
||||
jwt.verify(token, key, options, function (err, p) {
|
||||
assert.isNull(err);
|
||||
assert.equal(p.foo, 'bar');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('option: maxAge', function () {
|
||||
it('should error for claims issued before a certain timespan', function (done) {
|
||||
clock = sinon.useFakeTimers(1437018582500);
|
||||
var options = {algorithms: ['HS256'], maxAge: '321ms'};
|
||||
|
||||
jwt.verify(token, key, options, function (err, p) {
|
||||
assert.equal(err.name, 'TokenExpiredError');
|
||||
assert.equal(err.message, 'maxAge exceeded');
|
||||
assert.equal(err.expiredAt.constructor.name, 'Date');
|
||||
assert.equal(Number(err.expiredAt), 1437018582321);
|
||||
assert.isUndefined(p);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should not error if within maxAge timespan', function (done) {
|
||||
clock = sinon.useFakeTimers(1437018582500);
|
||||
var options = {algorithms: ['HS256'], maxAge: '600ms'};
|
||||
|
||||
jwt.verify(token, key, options, function (err, p) {
|
||||
assert.isNull(err);
|
||||
assert.equal(p.foo, 'bar');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('can be more restrictive than expiration', function (done) {
|
||||
clock = sinon.useFakeTimers(1437018582900);
|
||||
var options = {algorithms: ['HS256'], maxAge: '800ms'};
|
||||
|
||||
jwt.verify(token, key, options, function (err, p) {
|
||||
assert.equal(err.name, 'TokenExpiredError');
|
||||
assert.equal(err.message, 'maxAge exceeded');
|
||||
assert.equal(err.expiredAt.constructor.name, 'Date');
|
||||
assert.equal(Number(err.expiredAt), 1437018582800);
|
||||
assert.isUndefined(p);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('cannot be more permissive than expiration', function (done) {
|
||||
clock = sinon.useFakeTimers(1437018583100);
|
||||
var options = {algorithms: ['HS256'], maxAge: '1200ms'};
|
||||
|
||||
jwt.verify(token, key, options, function (err, p) {
|
||||
// maxAge not exceded, but still expired
|
||||
assert.equal(err.name, 'TokenExpiredError');
|
||||
assert.equal(err.message, 'jwt expired');
|
||||
assert.equal(err.expiredAt.constructor.name, 'Date');
|
||||
assert.equal(Number(err.expiredAt), 1437018583000);
|
||||
assert.isUndefined(p);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should error if maxAge is specified but there is no iat claim', function (done) {
|
||||
clock = sinon.useFakeTimers(1437018582900);
|
||||
var token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIifQ.0MBPd4Bru9-fK_HY3xmuDAc6N_embknmNuhdb9bKL_U';
|
||||
var options = {algorithms: ['HS256'], maxAge: '1s'};
|
||||
|
||||
jwt.verify(token, key, options, function (err, p) {
|
||||
assert.equal(err.name, 'JsonWebTokenError');
|
||||
assert.equal(err.message, 'iat required when maxAge is specified');
|
||||
assert.isUndefined(p);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user