I want to embed Grafana into my web application using AngularJS. The goal is, when user is in my application, she should be able to click on a button and load the Grafana UI. In itself, this is an easy task. To do this, I have apache proxying Grafana and returning any necessary CORS headers. The apache reverse proxy config is as follows:
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, Authorization, accept, client-security-token"
RewriteEngine on
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
RewriteCond %{REQUEST_METHOD} OPTIONS
ProxyPass / http://localhost:3000/
All works perfectly fine when no security is involved. The following code is a simple HTML/Javascript that shows what I am doing:
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="http://requirejs.org/docs/release/2.1.11/minified/require.js"></script>
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
<body >
<script>
var app = angular.module('myApp', []);
app.controller('MainCtrl', function ($scope, $http, $sce) {
$scope.trustSrc = function(src) {
console.log(src);
return $sce.trustAsHtml(src);
}
$http({
method : 'GET',
url : 'http://grafana-host.com',
}).success(function(response) {
$("#test").attr('src', 'http://grafana-host.com')
$("#test").contents().find('html').html(response);
}).error(function(error) {
console.log(error);
});
});
</script>
<div ng-app="myApp" ng-controller="MainCtrl">
<iframe id="test" style="position: absolute; top: 50px; left: 0px; bottom: 0px; right: 0px; width: 100%; height: 100%; border: none; margin: 0; padding: 0; overflow: hidden;"></iframe>
The challenge now is that once logged in into my application, user should not have to log in into Grafana again.
To resolve this issue, I set up Grafana to use Basic Auth. My goal is for my web app to pass basic auth to Grafana via the browser. Basically, when the user clicks on the button to open Grafana, I would issue a request via AngularJS. This request would include the required Authorization header to load Grafana. To do this, I augment the above code segment with the http blog after the url field:
headers : {
'Authorization' : 'Basic YWRtaW46YWRtaW4='
}
Also, in the success callback function, I replace the first instruction with:
$("#test").attr('src',"data:text/html;charset=utf-8," + escape(response))
Unfortunately, I do not seem to be able to get this to work.
I know this should work because I can simulate this behavior with ModHeader extension of Chrome browser. If I put the following header in ModHeader: Authorization: Basic YWRtaW46YWRtaW4=, it loads Grafana from without need to log in. And if I remove the Authorization header, I am prompted for login name and password again.
The grafana changes are pretty simple:
[auth.basic]
enabled = true
What am I missing? My guess is this is an AngularJS/Javascript thing.
Login into Grafana dashboard and Select the dashboard which You want to embed. From the dashboard click on (Panel Title -> Share -> Embed). Copy the HTML code shown below. You can now go into your source code and paste the copied HTML code into your HTML page.
On the Grafana page, go to the dashboard that you want to share. icon. On the Link tab, you can obtain the dashboard sharing link. Quit Grafana's current account, access the link obtained in the previous step, and verify whether the link can be opened.
Don't know if this is an option at the time the question was written, but we're doing this quite successfully by injecting an API token for authorization (http://docs.grafana.org/http_api/auth/).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With