Hapi Micro Auth Plugin
hapi-micro-auth is a Hapi plugin designed to integrate with the micro-auth authentication service, exposing its functionalities as an authentication provider within a Hapi server. It handles session management, user retrieval, and authentication routes by proxying requests to a configured micro-auth instance. The current stable version is 4.0.1. The project appears to have an inactive release cadence, with its last major update (4.0.0) in late 2020. Key differentiators include its tight coupling with the firstandthird/micro-auth service, providing a specific solution for projects already leveraging that authentication backend. It offers methods to interact with user data, session updates, and metadata management via `server.microauth` methods.
Common errors
-
Error: Plugin 'hapi-micro-auth' failed to register
cause The plugin's options are invalid, or a required dependency (like `micro-auth` itself or a specific Hapi version) is missing or incompatible.fixVerify that your `options` object for `hapi-micro-auth` aligns with the documented configuration, especially `host`. Ensure `@hapi/hapi` and `micro-auth` are installed and their versions are compatible with `hapi-micro-auth` v4.x. -
TypeError: Cannot read properties of undefined (reading 'getMe')
cause The `hapi-micro-auth` plugin was not successfully registered with the Hapi server, or the `server.microauth` namespace is not available when attempting to access its methods.fixEnsure `await server.register({ plugin: hapiMicroAuth, options: { /* ... */ } });` is called and completes successfully before any routes or handlers try to access `server.microauth` methods. Check server startup logs for registration errors. -
Authentication fails or redirects incorrectly (e.g., infinite redirect loops)
cause Misconfiguration of `host`, `hostRedirect`, `redirectTo`, or cookie options (`name`, `isSecure`, `isSameSite`) resulting in incorrect communication with the micro-auth service or improper cookie handling.fixDouble-check the `host` option points to the correct `micro-auth` endpoint. If `hostRedirect` is used, ensure it's also correct. Verify `redirectTo` for proper login/logout flows. Pay close attention to `cookie.isSecure` in production and `cookie.isSameSite` for browser compatibility, especially if your Hapi server and micro-auth service are on different domains.
Warnings
- breaking Version 4.0.0 introduced dependency updates and configuration changes. While specific breaking changes are not explicitly detailed in the changelog, a major version bump indicates potential incompatibilities with previous Hapi or micro-auth versions.
- breaking The default login route was changed from `/api/users/list` to `/api/users` in version 3.7.1. Applications relying on the previous endpoint will need to update their routing logic.
- gotcha The `SameSite` cookie attribute was updated in version 3.6.0. This might affect how cookies are handled by browsers, especially in cross-site contexts, potentially leading to authentication issues if not configured correctly.
- gotcha The `getMe` method calls the `/me` API endpoint of micro-auth, returning information suitable for the authenticated user, whereas `getUser` retrieves more general user information. Using `getMe` for public display of user data might expose sensitive details.
Install
-
npm install hapi-micro-auth -
yarn add hapi-micro-auth -
pnpm add hapi-micro-auth
Imports
- hapiMicroAuth
const hapiMicroAuth = require('hapi-micro-auth');import hapiMicroAuth from 'hapi-micro-auth';
- getMe
import { getMe } from 'hapi-micro-auth';server.microauth.getMe(token);
- plugin registration
server.register(hapiMicroAuth, { /* ... */ });await server.register({ plugin: hapiMicroAuth, options: { /* ... */ } });
Quickstart
import Hapi from '@hapi/hapi';
import hapiMicroAuth from 'hapi-micro-auth';
const init = async () => {
const server = Hapi.server({
port: 3000,
host: 'localhost'
});
await server.register({
plugin: hapiMicroAuth,
options: {
host: process.env.MICRO_AUTH_HOST ?? 'http://localhost:8081/auth', // URL to micro-auth service
routes: true, // Enable default auth routes (e.g., /login, /logout)
strategy: {
name: 'microauth',
mode: 'required' // 'required', 'optional', 'try'
},
cookie: {
name: 'auth_session',
isSecure: process.env.NODE_ENV === 'production',
ttl: 12960000000 // 150 days
}
}
});
server.route({
method: 'GET',
path: '/me',
handler: async (request, h) => {
try {
// Assuming 'microauth' is the strategy name from plugin options
const user = request.auth.credentials;
if (!user) {
return h.response('Not authenticated').code(401);
}
// Example of using a plugin method
const fullUser = await server.microauth.getMe(user.token);
return fullUser;
} catch (error) {
console.error('Error fetching user:', error);
return h.response('Internal Server Error').code(500);
}
},
options: {
auth: 'microauth' // Apply the authentication strategy
}
});
await server.start();
console.log(`Server running on ${server.info.uri}`);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();