【发布时间】:2015-08-31 05:09:56
【问题描述】:
上下文
我正在使用 Node.js 和 Express 开发的 Web 应用程序的多个位置嵌入 Kibana 4 仪表板。嵌入依赖于上下文,这意味着根据仪表板的嵌入位置,对 Elasticsearch 的查询会发生变化。
此外,某些嵌入仪表板的页面仅限于某些具有正确权限的用户。
由于 Kibana 4 中尚未实现身份验证,因此通过更改仪表板嵌入 URL 中的查询,任何用户都可以显示他们无权访问的页面的仪表板。
我们的解决方案
我们的想法是阻止任何与 Kibana(端口 5601)的外部连接,并通过我们的 Web 应用程序创建一个自定义 URL 并检查用户权限(一种代理)。如果用户有权限,那么我们的 Web 应用会将 HTTP 查询转发到 Kibana。由于我们的网络应用和 Kibana 位于同一台服务器上,因此不会阻止这些查询。
要路由自定义 URL 并检查权限,我们有以下内容:
app.route('/items/:itemId/analytics/*')
.all(api.requiresAccess('user'),
api.requiresPermissions('item', 'modify'),
items.getAnalytics);
然后我们在getAnalytics函数中使用Request:
exports.getAnalytics = function (req, res) {
var itemId = req.item.id;
var kibanaParamsRegexp = /analytics\/(.*)/;
var kibanaParamsMatch = kibanaParamsRegexp.exec(req.originalUrl);
var kibanaParams = kibanaParamsMatch[1];
var method = req.method;
var dashboardId = 'Standard-Dashboard';
var kibanaDashboardURL = 'http://localhost:5601';
if (kibanaParams === '') { // First request to get the dashboard
kibanaDashboardURL += '/#/dashboard/' + dashboardId + '?embed' +
'&_a=(query:(query_string:(analyze_wildcard:!t,query:\'path:' + itemId + '\')))' +
'&_g=(time:(from:now-1y,mode:quick,to:now))';
} else { // Following requests to get the dashboard
kibanaDashboardURL += '/' + kibanaParams;
}
app.logger.info('Received from the dashboard: ' + req.originalUrl);
app.logger.info('Requesting to Kibana: ' + kibanaDashboardURL);
app.logger.info('Query body: ' + JSON.stringify(req.body));
if (method === 'POST') {
var options = {
url: kibanaDashboardURL,
json: true,
body: req.body
};
request.post(options,
function (err, httpResponse, body) {
if (err) {
return console.log('POST failed: ', err);
}
console.log('POST successful. Sever response: ', body);
}).pipe(res);
} else if (method === 'GET' || method === 'HEAD') {
request.get(kibanaDashboardURL).pipe(res);
}
};
因此,而不是http://localhost:5601/#/dashboard/Standard-dashboard?embed&_a=(query:(query_string:(analyze_wildcard:!t,query:'path: 5539e831b5b79bf9f4b06a3c')))&_g=(time:(from:now-1y,mode:quick,to:now)),
我必须使用检查权限的http://localhost:8000/items/5539e831b5b79bf9f4b06a3c/analytics/。
问题
第一个请求,主要是GETs 和少数POSTs,都顺利通过了。但是在某些时候,我有一个POST 请求,它收到一个 500 Internal Sever 错误以响应该请求,这会停止仪表板加载。
为了尝试找出问题,我比较了仪表板负载与原始 Kibana URL 和通过 Web 应用程序重定向的 URL 之间的网络流量(在 Web 检查器中)。开头是相同的,但在某些时候(在请求收到 500 错误返回之前),仪表板通过原始 URL 加载会发出一个请求,该请求未通过重定向的 URL 完成。请求是 POST 到 http://localhost:5601/elasticsearch/_mget?timeout=0&ignore_unavailable=true&preference=1434374357241 的请求,正文如下:{"docs":[{"_index":".kibana","_type":"dashboard","_id":"Standard-Dashboard"}]}。
这个请求似乎非常重要,因为它包含仪表板 ID,我想它的缺失是稍后产生 500 错误的原因。但是我不知道为什么当我通过网络应用重定向查询时没有发送这个请求。
我也尝试过使用 http-proxy 和 express-http-proxy 模块,但我遇到了同样的问题。
【问题讨论】:
-
您的问题解决了吗?我对您的解决方案感兴趣!
-
@DaTebe 我不再从事有此问题的项目。据我记得,我们没有找到解决办法。我没有检查建议的答案,所以我不能说他们是否解决了问题。
-
干草。感谢您的答复!您的 URL '/items/:itemId/analytics/*' 让我想起了一个使用 Kibana 和代理的学习自动循环系统。你在那个特定的应用程序上工作吗? (Graasp.eu)
-
@DaTebe 不错的收获!是的,这是我在 Graasp.eu 工作时遇到的问题
-
@DaTebe 我联系了他们,他们找到了合适的解决方案。您可以联系Andrii Vozniuk。祝你的论文好运!
标签: proxy httprequest kibana kibana-4