hapi
hapi copied to clipboard
Sandbox default auth strategy
Support plan
- is this issue currently blocking your project? (yes/no): no
- is this issue affecting a production system? (yes/no): no
Context
- node version: v12.16.1
- module version: v20.0.0
- environment (e.g. node, browser, native): node
- used with (e.g. hapi application, another framework, standalone, ...): hapi
- any other relevant information: N/A
What problem are you trying to solve?
I want to sandbox the default strategy set in a plugin. Since server.auth.strategy() is sandboxed, it would make sense to sandbox server.auth.default() as well. In my case, I have 2 plugins, one for the API and the other is for the site renderer. The API has session strategy by default, but because server.auth.default() is not sandboxed, all the routes registered by the renderer have the same default strategy.
(There are of course several workarounds to this issue such as using server.rules() or set auth: false in the renderer, but I would like to see a more consistent sandboxing behaviour).
const Api = {
name: 'api',
register(server) {
await server.register(Cookie);
server.auth.strategy('session', 'cookie', {});
server.auth.default('session');
}
};
const Renderer = {
name: 'renderer',
register(server) {
server.routes({ path: '/{p*}', method: 'GET', handler() {} }); // Uses session by default
}
};
function bootstrap() {
const server = new Hapi.Server();
await server.register(Api, Renderer);
}
bootstrap();
Do you have a new or modified API suggestion to solve the problem?
N/A
I agree that it would be great for there to be a way to set a default auth strategy locally to a plugin. And furthermore, it would be great to unify the different ways of talking about when something acts server-wide, within a plugin, or within a plugin but "inheriting" via the plugin registration ("realm") hierarchy. Here are a few examples of different behaviors:
server.auth.default()is global to the server.- I believe
server.auth.strategy()is global to the server too (but naming conflicts are detected and fail early, just like with route, cookies, decorations, etc.). server.bind()andserver.path()are local to the current plugin.server.rules()processors are local to the current plugin and inherit from parent realms/plugins.server.ext()request lifecycle extensions are global to the server by default but can be scoped locally to the plugin using the{ sandbox: 'plugin' }option.- The
server.register()registration optionroutes.prefixaffects the plugin(s) being registered and their children realms/plugins. - You can specify route defaults global to the server on
server.options.routes. You can achieve the same thing locally to a plugin with a little effort usingserver.rules(), and this could in theory interact withserver.auth.default(). The timing of both these calls relative to callingserver.route()also comes into play.
It is a fair amount of work, but some day it might be nice to take this all in and unify some of these behaviors/APIs as well as the language we use around them.
@devinivy I'm sure server.auth.strategy is sandboxed. Not sure about server.auth.scheme though
I think this is a valid discussion about server.auth.default() whether or not server.auth.strategy() is sandboxed, but I do believe that it is not sandboxed. Perhaps it seems that way because you are trying to use the strategy in one plugin before it is defined in another. This example gives us a server that initializes properly, though:
const server = Hapi.server();
await server.register({
name: 'x',
register: (srv) => {
srv.auth.scheme('my-scheme', () => ({ authenticate: () => null }));
srv.auth.strategy('my-strategy', 'my-scheme');
}
});
await server.register({
name: 'y',
register: (srv) => {
srv.route({
method: 'get',
path: '/',
options: {
auth: 'my-strategy',
handler: () => null
}
});
}
});
await server.initialize();
Oh yeah @devinivy you're right. Would be nice if it is sandboxed as well.