如何将 Hapi.js 插件应用到特定路由?
How to apply a Hapi.js plugin to specific routes?
我有一个用 Hapi.js 构建的服务器。我创建了一个插件来限制对某些本地网络 IP 地址的访问,如下所示:
exports.register = function (server, options, next) {
server.ext({
type: 'onRequest',
method: function (request, reply) {
console.log(request);
if (
request.info.remoteAddress.indexOf("192.") !== 0 &&
request.info.remoteAddress.indexOf("127.") !== 0
) {
return reply.view('error', {
error: "I DON'T LIKE YOU"
});
}
return reply.continue();
}
});
next();
};
exports.register.attributes = {
pkg: { "name": "localOnly" }
};
我只想将此插件应用于“/pathA”,同时让所有用户都可以访问“/pathB”和“/pathC”。因此我尝试这样做:
const server = new Hapi.Server();
server.connection({ port: 8000 });
server.register(require('vision'), err => {
if (err) throw err;
server.views(/* removed for brevity */);
server.route({ method: 'GET', path: '/pathB', handler: handlerB });
server.route({ method: 'GET', path: '/pathC', handler: handlerC });
server.register(require('./plugins/localOnly.js'), err => {
if (err) throw err;
server.route({ method: 'GET', path: '/pathA', handler: handlerA });
server.start(/* removed for brevity */);
});
});
但是,我的插件似乎拦截了所有连接。谁能告诉我我做错了什么?如果你建议我做一个完整的重构也没关系。我只是在这个阶段规划应用程序,想 Hapi.js 试一试。
是否需要在插件中?如果没有,您可以使用路由级扩展点。例如:
路由级扩展
const restrict = function (request, reply) {
if (/^(192|127)/.test(request.info.remoteAddress)) {
return reply('Blocked');
}
return reply.continue();
};
server.route({
config: {
ext: {
onPreAuth: { method: restrict }
}
},
method: 'GET',
path: '/pathA',
handler: function (request, reply) {
reply('Hello!');
}
});
另一种使用插件的方法:
使用sandbox: plugin
在插件内添加路由
const plugin = function (server, options, next) {
const restrict = function (request, reply) {
if (/^(192|127)/.test(request.info.remoteAddress)) {
return reply('Blocked');
}
return reply.continue();
};
// only applies to route in this plugin
server.ext('onPreAuth', restrict, { sandbox: 'plugin' });
server.route({
method: 'GET',
path: '/pathA',
handler: function (request, reply) {
reply('Hello!');
}
});
return next();
};
对于较新版本的 Hapi(当前为 v17),您需要将路由选项作为 route.options.plugins['myPluginName']
传递,例如
{
method: 'GET',
path: '/home',
options: {
plugins: {
myPluginName: true
}
}
}
这可以在挂接到 onPreAuth
或更高版本的 ext
下的插件中获取。例如
register: async (server, options) => {
server.ext({
type: 'onPreAuth',
method: async (request, h) => {
// Exit early if the route is not configured for this route
if (!request.route.settings.plugins.myPluginName) { return h.continue }
// ... runs before the route handler ...
}
})
}
请注意,挂钩必须晚于 Hapi lifecycle 中的 onRequest
,因为此时尚未加载路由。如果你想访问身份验证的东西,那么你将不得不使用 onPostAuth
.
这种方法的好处是在路由和插件之间松耦合。
我有一个用 Hapi.js 构建的服务器。我创建了一个插件来限制对某些本地网络 IP 地址的访问,如下所示:
exports.register = function (server, options, next) {
server.ext({
type: 'onRequest',
method: function (request, reply) {
console.log(request);
if (
request.info.remoteAddress.indexOf("192.") !== 0 &&
request.info.remoteAddress.indexOf("127.") !== 0
) {
return reply.view('error', {
error: "I DON'T LIKE YOU"
});
}
return reply.continue();
}
});
next();
};
exports.register.attributes = {
pkg: { "name": "localOnly" }
};
我只想将此插件应用于“/pathA”,同时让所有用户都可以访问“/pathB”和“/pathC”。因此我尝试这样做:
const server = new Hapi.Server();
server.connection({ port: 8000 });
server.register(require('vision'), err => {
if (err) throw err;
server.views(/* removed for brevity */);
server.route({ method: 'GET', path: '/pathB', handler: handlerB });
server.route({ method: 'GET', path: '/pathC', handler: handlerC });
server.register(require('./plugins/localOnly.js'), err => {
if (err) throw err;
server.route({ method: 'GET', path: '/pathA', handler: handlerA });
server.start(/* removed for brevity */);
});
});
但是,我的插件似乎拦截了所有连接。谁能告诉我我做错了什么?如果你建议我做一个完整的重构也没关系。我只是在这个阶段规划应用程序,想 Hapi.js 试一试。
是否需要在插件中?如果没有,您可以使用路由级扩展点。例如:
路由级扩展
const restrict = function (request, reply) {
if (/^(192|127)/.test(request.info.remoteAddress)) {
return reply('Blocked');
}
return reply.continue();
};
server.route({
config: {
ext: {
onPreAuth: { method: restrict }
}
},
method: 'GET',
path: '/pathA',
handler: function (request, reply) {
reply('Hello!');
}
});
另一种使用插件的方法:
使用sandbox: plugin
在插件内添加路由
const plugin = function (server, options, next) {
const restrict = function (request, reply) {
if (/^(192|127)/.test(request.info.remoteAddress)) {
return reply('Blocked');
}
return reply.continue();
};
// only applies to route in this plugin
server.ext('onPreAuth', restrict, { sandbox: 'plugin' });
server.route({
method: 'GET',
path: '/pathA',
handler: function (request, reply) {
reply('Hello!');
}
});
return next();
};
对于较新版本的 Hapi(当前为 v17),您需要将路由选项作为 route.options.plugins['myPluginName']
传递,例如
{
method: 'GET',
path: '/home',
options: {
plugins: {
myPluginName: true
}
}
}
这可以在挂接到 onPreAuth
或更高版本的 ext
下的插件中获取。例如
register: async (server, options) => {
server.ext({
type: 'onPreAuth',
method: async (request, h) => {
// Exit early if the route is not configured for this route
if (!request.route.settings.plugins.myPluginName) { return h.continue }
// ... runs before the route handler ...
}
})
}
请注意,挂钩必须晚于 Hapi lifecycle 中的 onRequest
,因为此时尚未加载路由。如果你想访问身份验证的东西,那么你将不得不使用 onPostAuth
.
这种方法的好处是在路由和插件之间松耦合。