在项目中要求将grafana-web完全集成到企业应用程序中。
有些观点是:
由于Grafana没有这样的东西,我打算将其加载到iframe中并将XSS加载到其中以隐藏按钮(两个UI都将从同一个域加载)。
答案 0 :(得分:1)
我完全理解并接受Torkel和Grafana团队的决定,不要只在前端设置只读模式作为"邪恶"用户可以轻松查询周围的后端,因此从安全角度来看,他们是对的。
但正如你所看到的,即使只是作为一个视觉怪癖,一些边缘案例/项目也需要这样做。
警告:为了确保你得到它,这是一个grafana-web的视觉样式,并没有提供任何安全性,一个"邪恶"用户仍然可以访问所有内容。
所以我的实施方式如下:
这是由DOMContentLoaded触发的自定义程序代码:
// Don't forget to load the mutation-summary.js lib
function iframeLoad (iframe) {
// Disable this if you want users to have access to playground buttons like:
// add Rows, edit Panels, dashboard settings ...
readOnlyMode = true;
// This is the iframe "window"
var iframe_window = iframe.contentWindow;
// This is the iframe "document" under which the MutationObserver will look for DOM changes
var iframe_document = iframe.contentDocument;
var queries = [{
// This is the main menu of grafana
element: '.navbar-brand-btn'
},{
// This is the dashboard selection right of the main menu
element: '.navbar-page-btn'
},{
// This is the share button appearing inside the .dashnav-action-icons, we don't want to allow
// this to anybody, as it's exposes the real url, thus bypassing this code
element: 'li[ng-show="::dashboardMeta.canShare"]'
},{
// This is the dashboard delete button, under dashboard setting button
element: 'a[ng-click="deleteDashboard();"]'
}];
if ( readOnlyMode ) {
queries.push({
// This is the three vertical dots button to open the row menu/edit
element: '.dash-row-menu-grip'
});
queries.push({
// This is the bottom "+ ADD ROW" button
element: '.add-row-panel-hint'
});
queries.push({
// This is the share button right of the dashboard menu
element: '.dashnav-action-icons'
});
queries.push({
// This is the "Panel" menu triggered by clicking the Panel name
element: '.panel-menu'
});
}
var observer;
observer = new MutationSummary({
callback: function (changes) {
changes.forEach(function (change) {
change.added.forEach(function (el) {
iframe_window.angular.element(el).addClass('ng-hide');
});
});
// Normally we disconnect here to free resources, but on new dashboards
// the buttons will be re-rendered by Angular, so we keep this to block that behaviour
//observer.disconnect();
},
queries: queries,
rootNode: iframe_document
});
// Hide the elements if they are already generated before we registred the Observer
// is a race condition afterall "Angular rendering" vs "registering the Observer"
queries.forEach( function (el) {
if ( iframe_window && iframe_window.angular ) {
iframe_window.angular.element(el.element).addClass('ng-hide');
}
});
// Remove the mask or move the iframe into view if needed
// [YOUR CODE HERE]
}
此方法针对grafana版本4.0.0-1476697633pre1(以及当前在play.grafana.org中运行的版本)进行了测试。
升级grafana后,会尝试更新github页面中的代码。
可以在我的github页面上使用iframe中的play.grafana.org找到完整的示例,并且play.grafana不在您的域中,可以通过启动它来禁用Chrome中的同源策略:
google-chrome --disable-web-security --user-data-dir