diff --git a/lib/strategy.js b/lib/strategy.js index 42730d9..772035a 100644 --- a/lib/strategy.js +++ b/lib/strategy.js @@ -48,6 +48,9 @@ var passport = require('passport-strategy') * @param {boolean} [options.passReqToCallback=false] - When `true`, the * `verify` function receives the request object as the first argument, * in accordance with the `{@link Strategy~verifyWithReqFn}` signature. + * @param {boolean} [options.allowQueryParameter=true] - When `true`, the strategy + * also attempts to obtain `access_token` from a query string. Otherwise + * the usage of `access_token` query parameter is forbidden and strategy will fail. * @param {Strategy~verifyFn|Strategy~verifyWithReqFn} verify - Function which * verifies access token. * @@ -88,6 +91,8 @@ function Strategy(options, verify) { this._scope = (Array.isArray(options.scope)) ? options.scope : [ options.scope ]; } this._passReqToCallback = options.passReqToCallback; + this._allowQueryParameter = + typeof options.allowQueryParameter === 'undefined' ? true : options.allowQueryParameter; } // Inherit from `passport.Strategy`. @@ -135,7 +140,9 @@ Strategy.prototype.authenticate = function(req) { } if (req.query && req.query.access_token) { - if (token) { return this.fail(400); } + if (token || !this._allowQueryParameter) { + return this.fail(400); + } token = req.query.access_token; } diff --git a/test/strategy.test.js b/test/strategy.test.js index ed56d98..f147507 100644 --- a/test/strategy.test.js +++ b/test/strategy.test.js @@ -13,6 +13,10 @@ describe('Strategy', function() { expect(strategy.name).to.equal('bearer'); }); + it('should default the allowQueryParameter option to true', () => { + expect(strategy._allowQueryParameter).to.be.true; + }) + it('should authenticate request with bearer scheme', function(done) { var strategy = new Strategy(function(token, cb) { return cb(null, { id: '248289761001' }); @@ -65,10 +69,11 @@ describe('Strategy', function() { .authenticate(); }); // should authenticate request with token in form-encoded body parameter - it('should authenticate request with token in URI query parameter', function(done) { - var strategy = new Strategy(function(token, cb) { - return cb(null, { id: '248289761001' }); - }); + describe('when the allowQueryParameter option is true', () => { + it('should authenticate request with token in URI query parameter', function(done) { + var strategy = new Strategy({ allowQueryParameter: true }, function(token, cb) { + return cb(null, { id: '248289761001' }); + }); chai.passport.use(strategy) .request(function(req) { @@ -81,8 +86,29 @@ describe('Strategy', function() { done(); }) .authenticate(); - }); // should authenticate request with token in URI query parameter + }); // should authenticate request with token in URI query parameter + }); + describe('when the allowQueryParameter option is false', () => { + it('should NOT authenticate request with token in URI query parameter', function (done) { + const strategy = new Strategy({ allowQueryParameter: false }, function (token, cb) { + return cb(null, { id: '248289761001' }); + }); + + chai.passport + .use(strategy) + .request(function (req) { + req.query = {}; + req.query.access_token = 'mF_9.B5f-4.1JqM'; + }) + .fail(function (status) { + expect(status).to.equal(400); + done(); + }) + .authenticate(); + }); // should NOT authenticate request with token in URI query parameter + }); + it('should challenge request with realm', function(done) { var strategy = new Strategy({ realm: 'example' }, function(token, cb) { throw new Error('verify function should not be called');