Node 8 hit LTS status recently and now we have full async/await support (yay!) on a stable Node version. This also means that a lot of JS libraries and frameworks have the oppurtunity to do code cleanups / rewrites to give us simpler APIs and faster / simpler code. KoaJS was the first to get on this train and now HapiJS also joined the party and released a big upgrade with v17.
In this short post we will look at setting up basic authentication and logging functionality with hapi v17 (since I usually need this for all projects). First thing of note is that since v17 is a major re-write, a lot of plugins for hapi have / had to be re-written as well. Two plugins that I usually rely on hapi-auth-jwt-2 and good right now do not work with v17. However, with hapi-auth-jwt2 plugin there is already a PR so it is just a matter of forking it for now and applying the PR. For logging we will use hapi-pino. So the basic hapi v17 server setup looks like -
'use strict';
const Hapi = require('hapi');
const Config = require('config');
const HapiAuthJWT = require('hapi-auth-jwt2');
const HapiPino = require('hapi-pino');
const Routes = require('./lib/routes/');
const Token = require('./lib/services/token');
// Create a server with a host and port
const server = new Hapi.Server({
port: Config.get('api.port'),
routes: { cors: Config.get('api.cors') }
});
const init = async () => {
// Register plugins
await server.register(HapiAuthJWT);
await server.register(HapiPino);
// Auth setup
server.auth.strategy('jwt', 'jwt',{
key: Config.get('token.secret'),
validate: Token.validate,
verifyOptions: { algorithms: ['HS256'] }
});
server.auth.default('jwt');
// Routes
server.route(Routes);
await server.start();
return server;
};
init()
.catch((err) => console.error(err));
module.exports = server;
Sample routes -
const PingController = require('../controllers/ping_controller');
const MessagesController = require('../controllers/messages_controller');
const TokenController = require('../controllers/token_controller');
const UsersController = require('../controllers/users_controller');
const SharedMessagesController = require('../controllers/shared_messages_controller');
const routes = [
{ method: 'GET', path: '/ping', options: { auth: false }, handler: PingController.show },
{ method: 'POST', path: '/token', options: { auth: false }, handler: TokenController.create },
{ method: 'GET', path: '/me', options: { auth: 'jwt' }, handler: UsersController.show },
{ method: 'GET', path: '/messages', options: { auth: 'jwt' }, handler: MessagesController.index },
{ method: 'GET', path: '/messages/{id}', options: { auth: 'jwt' }, handler: MessagesController.show },
{ method: 'DELETE',path: '/messages/{id}', options: { auth: 'jwt' }, handler: MessagesController.delete },
{ method: 'PUT', path: '/messages/{id}', options: { auth: 'jwt' }, handler: MessagesController.update },
{ method: 'POST', path: '/messages', options: { auth: false }, handler: MessagesController.create },
{ method: 'GET', path: '/sharedMessages',options: { auth: false }, handler: SharedMessagesController.index }
];
module.exports = routes;
And a sample handler -
class Ping {
show(request, h) {
return { pong: true };
}
}
module.exports = new Ping();
That's it, we are all set with a simple hapi v17 server with JWT authentication & logging and for sure it is simpler and faster.