MonkeyBonkey
MonkeyBonkey

Reputation: 47871

should I create a hapijs plugin or use server.ext to screen for an api-key in the header

So I'd like to check all http routes to my hapi rest api for a valid api key. I don't want to use an auth plugin as I will also have basic auth on some routes in addition to the api token check. I'm used to doing this as middleware in express, but what's the right way in hapi?

Should I create my own plugin or instead use server.ext to accomplish this.. or should I do it yet another way?

So far this is the way I've done it

server.ext('onRequest', function (request, next) {

    //make sure its https
    if(request.headers['x-forwarded-proto'] && request.headers['x-forwarded-proto'] === "http") {
        return next(Boom.badRequest('ssl is required'));
    }
    else
    {
        if (request.headers['x-api-key'] != apiToken) {
            return next(Boom.unauthorized('api key is incorrect'));
        }
        else
        {
            next();
        }
    }
});

Upvotes: 3

Views: 1718

Answers (2)

uadnal
uadnal

Reputation: 11435

While Gergo's reponse is good, I have a similar use case where I also need strategies to behave in such a way that:

A (Succeed) --> B (Succeed) --> Handler

A (Fail) --> reply(4xx) || A(succeed) --> B (fail) --> reply(4xx)

I handled it in this way

server.ext('onPostAuth', function(request, reply) {
  request.server.auth.test('A', request, function(err) {
    return err ? reply(err) : reply.continue();
  });
});

server.ext('onPostAuth', function(request, reply) {
  request.server.auth.test('B', request, function(err) {
    return err ? reply(err) : reply.continue();
  });
});

Upvotes: 0

Gergo Erdosi
Gergo Erdosi

Reputation: 42048

I would use an authentication plugin. You can use multiple authentication strategies at the same time, you are not limited to one. Here is an example how to do it:

var Hapi = require('hapi');
var server = new Hapi.Server(3000);

server.pack.register([require('hapi-auth-basic'), require('hapi-auth-cookie')], function(err) {

  server.auth.strategy('simple', 'basic', { ... });
  server.auth.strategy('session', 'cookie', { ... });

  server.route({
    method: 'GET',
    path: '/',
    auth: {
      strategies: ['simple', 'session']
    },
    handler: function(request, reply) {
      reply('success');
    }
  });

  server.start(function() {
    console.log('Server running at:', server.info.uri);
  });

});

See Authentication for more details:

When specifying one strategy, you may set the strategy property to a string with the name of the strategy. When specifying more than one strategy, the parameter name must be strategiesand should be an array of strings each naming a strategy to try. The strategies will then be attempted in order until one succeeds, or they have all failed.

Upvotes: 1

Related Questions