diff --git a/README.md b/README.md index e5bfa89..50f5545 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,7 @@ signature `function(decoded, callback)` where: - `algorithms` - list of allowed algorithms - `urlKey` - (***optional***) if you prefer to pass your token via url, simply add a `token` url parameter to your request or use a custom parameter by setting `urlKey` - `cookieKey` - (***optional***) if you prefer to pass your token via a cookie, simply set the cookie `token=your.jsonwebtoken.here` or use a custom key by setting `cookieKey` +- `tokenType` - (**optinal**) allow custom token type, e.g. Authorization: \ 12345678, default is none. ### verifyOptions let you define how to Verify the Tokens (*Optional*) diff --git a/lib/extract.js b/lib/extract.js index 7e4659b..91f96d8 100644 --- a/lib/extract.js +++ b/lib/extract.js @@ -6,17 +6,22 @@ var Boom = require('boom'); // error handling https://github.com/hapijs/boom */ module.exports = function (request, options) { - + // The key holding token value in url or cookie defaults to token var urlKey = typeof options.urlKey === 'string' ? options.urlKey : 'token'; var cookieKey = typeof options.cookieKey === 'string' ? options.cookieKey : 'token'; var auth; - + if(request.query[urlKey]) { // tokens via url: https://github.com/dwyl/hapi-auth-jwt2/issues/19 auth = request.query[urlKey]; } // JWT tokens in cookie: https://github.com/dwyl/hapi-auth-jwt2/issues/55 else if (request.headers.authorization) { - auth = request.headers.authorization; + if (typeof options.tokenType === 'string') { + var token = request.headers.authorization.match(new RegExp(options.tokenType + '\\s+([^$]+)', 'i')); + auth = token === null ? null : token[1]; + } else { + auth = request.headers.authorization; + } } else if (request.headers.cookie) { auth = Cookie.parse(request.headers.cookie)[cookieKey]; diff --git a/lib/index.js b/lib/index.js index 2ab7a00..ad5834c 100644 --- a/lib/index.js +++ b/lib/index.js @@ -31,15 +31,15 @@ internals.implementation = function (server, options) { if (!token && request.auth.mode === 'optional') { return reply.continue({ credentials: {} }); } - + if (!token) { - return reply(Boom.unauthorized('Missing auth token')); + return reply(Boom.unauthorized(null, 'Token')); } - + if (!extract.isValid(token)) { return reply(Boom.unauthorized('Invalid token format', 'Token')); } - + var keyFunc = (internals.isFunction(options.key)) ? options.key : function (decoded, callback) { callback(null, options.key); }; var decoded; diff --git a/test/custom-parameters-server.js b/test/custom-parameters-server.js index e16086a..15b2bac 100644 --- a/test/custom-parameters-server.js +++ b/test/custom-parameters-server.js @@ -32,7 +32,8 @@ server.register(require('../'), function (err) { validateFunc: validate, verifyOptions: { algorithms: [ 'HS256' ] }, urlKey: 'customUrlKey', // This is really what we are testing here - cookieKey: 'customCookieKey' // idem + cookieKey: 'customCookieKey', // idem + tokenType: 'MyAuthScheme' }); server.route([ diff --git a/test/custom-parameters-test.js b/test/custom-parameters-test.js index 16a935d..ddea70a 100644 --- a/test/custom-parameters-test.js +++ b/test/custom-parameters-test.js @@ -76,7 +76,7 @@ test("Authorization Header should take precedence over any cookie - custom param method: "POST", url: "/privado", headers: { - authorization: "Bearer "+token, + authorization: "MyAuthScheme " + token, cookie : "customCookieKey=malformed.token" + cookie_options } }; @@ -97,7 +97,7 @@ test("Valid Google Analytics cookie should be ignored - custom parameters", func method: "POST", url: "/privado", headers: { - authorization: "Bearer "+token, + authorization: "MyAuthScheme "+token, cookie : GA } }; @@ -114,7 +114,7 @@ test("Valid Google Analytics cookie should be ignored (BAD Header Token) - custo method: "POST", url: "/privado", headers: { - authorization: "Bearer "+token, + authorization: "MyAuthScheme "+token, cookie : GA } }; @@ -202,3 +202,30 @@ test("Access restricted content (with VALID Token) - custom parameters", functio t.end(); }); }); + +test("Attempt to access restricted content using inVALID header tokenType - custom parameters", function(t) { + var token = JWT.sign({ id:123,"name":"Charlie" }, 'badsecret'); + var options = { + method: "POST", + url: "/privado", + headers: { Authorization : "InvalidAuthScheme " + token } + }; + server.inject(options, function(response) { + t.equal(response.statusCode, 401, "Invalid token should error!"); + t.end(); + }); +}); + +test("Access restricted content (with VALID Token and header tokenType) - custom parameters", function(t) { + var token = JWT.sign({ id:123,"name":"Charlie" }, secret); + var options = { + method: "POST", + url: "/privado", + headers: { Authorization : "MyAuthScheme " + token } + }; + + server.inject(options, function(response) { + t.equal(response.statusCode, 200, "VALID Token should succeed!"); + t.end(); + }); +});