Skip to content

Instantly share code, notes, and snippets.

@timotgl
Created May 29, 2017 16:19
Show Gist options
  • Save timotgl/856ad407d3a5db3bd01058d48cd5433d to your computer and use it in GitHub Desktop.
Save timotgl/856ad407d3a5db3bd01058d48cd5433d to your computer and use it in GitHub Desktop.
How to combine two hapi.js authentication strategies which both use a bearer token from the authorization request header (hapi auth scheme for ambiguous token). ES6 with async/await.
const Boom = require('boom');
const headerPattern = /^Bearer (.+)/;
const testAuth = (request, strategy) => new Promise((resolve, reject) => {
request.server.auth.test(strategy, request, (error, credentials) => {
if (error === null) {
resolve(credentials);
} else {
reject(error);
}
});
});
/*
* Derive auth strategy to be used from the bearer token.
*/
const strategyForToken = (token) => {
let strategy = false;
if (conditionToDetectFirstStrategy) {
strategy = 'firstStrategyHere';
} else if (conditionToDetectSecondStrategy) {
strategy = 'secondStrategyHere';
}
return strategy;
};
/*
* Extract bearer token from request and identify which auth strategy it is meant for.
*/
const authenticate = async (request, reply) => {
// Reject missing or invalid header.
const header = request.headers.authorization;
if (!header || !headerPattern.test(header)) {
return reply(Boom.badRequest('Missing or invalid authorization header'), {}, {});
}
const token = header.match(headerPattern)[1];
const strategy = strategyForToken(token);
if (!strategy) {
return reply(Boom.badRequest('Unable to determine auth strategy'), {}, {});
}
try {
const credentials = await testAuth(request, strategy);
// Remember which strategy was successfully tested.
const artifacts = { actualStrategy: strategy };
return reply.continue({ credentials, artifacts });
} catch (error) {
return reply(error, {}, {});
}
};
module.exports = {
scheme: () => ({ authenticate })
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment