Reverse Proxy With Node

Howdy,

I am attempting to embed a grafana panel in an iframe on my website, but the POST request for the query never returns any data,

and it tells me my request is bad with a 400 error. I have my request going through a NodeJs Express proxy listening on port 8000 that forwards it to my local Grafana server running on port 8080. The middleware the handles this is below,

app.use('/grafana/', proxy("http://localhost:8080/", {
    proxyReqOptDecorator: function(proxyReqOpts, srcReq) {
      proxyReqOpts.headers['Authorization'] = `Bearer ${MY_API_KEY_HERE}`;
      return proxyReqOpts;
  }
}))

(EDIT: Here’s the proxy package I am using: express-http-proxy )

The problem, I think, is I may have some properties in my grafana ini file incorrect. Right now, I have the following properties in my grafana ini file,

[server]

 protocol = http
 http_addr = localhost
 http_port = 8080
 root_url = http://localhost:8000/grafana/
 serve_from_sub_path = true

Does any one see any problems or have any idea what the issue might be? Any help would be greatly appreciated!

Thanks!

Try disabling serve_from_sub_path or changing the proxy url to http://localhost:8080/grafana/

Still returning a 400 error with the query POST.

If this helps, this is how I am putting the panel in the iframe:

 <iframe src="http://localhost:8000/grafana/d-solo/_yYHd42Zk/dfas-demo?orgId=1&from=1506862953434&to=1569934953434&panelId=2" width="450" height="200" frameborder="0"></iframe>    

Interestingly, if I change the host port from 8000 to 8080 (where Grafana is running), I get the data returned, even though it’s not going through the proxy and getting the API key attached to it,

I assume this is because I am logged on the current session. It’s still strange this gives me data, no?

That is interesting, you may want to enable debug logging in Grafana and see if there’s anything useful in the logs.

So you can see POST request coming in on the debug logs here,

t=2019-10-01T11:16:08-0400 lvl=dbug msg="User granted access to execute action" logger=dashboard.permissions userId=0 orgId=1 uname= dashId=1 action=View

t=2019-10-01T11:16:08-0400 lvl=dbug msg="User granted access to execute action" logger=dashboard.permissions userId=0 orgId=1 uname= dashId=1 action=Edit

t=2019-10-01T11:16:08-0400 lvl=dbug msg="User granted access to execute action" logger=dashboard.permissions userId=0 orgId=1 uname= dashId=1 action=Edit

t=2019-10-01T11:16:08-0400 lvl=dbug msg="User granted access to execute action" logger=dashboard.permissions userId=0 orgId=1 uname= dashId=1 action=Admin

t=2019-10-01T11:16:08-0400 lvl=info msg="Request Completed" logger=context userId=0 orgId=1 uname= method=POST path=/api/tsdb/query status=400 remote_addr=127.0.0.1 time_ms=13 size=39 referer="http://localhost:8000/grafana/d-solo/_yYHd42Zk/dfas-demo?orgId=1&from=1506862953434&to=1569934953434&panelId=2"

Would a userId of 0 be a problem? How is a user associated with a request? Through the API key?

Update: I enabled query logging and when I get to the point where the iframe issues the POST request to api/tsdb/query endpoint, I got the following output:

t=2019-10-02T08:41:11-0400 lvl=info msg="[SQL] SELECTid,org_id,name,key,role,created,updated,expiresFROMapi_keyWHERE (org_id=? AND name=?) LIMIT 1 []interface {}{1, \"dfas-admin\"} - took: 0s" logger=sqlstore.xorm

It doesn’t seem like it’s finding my panels when it’s coming from the proxy? I didn’t configure my local database at all, the one where Grafana stores panels and whatnot. Does that need to be configured before use?

So, I figured out the issue. The proxy wasn’t forwarding the request body to grafana. If you use NodeJs, you need to make sure to use

app.use(bodyParser.json())

to ensure the request body is properly parsed and forwarded to the grafana server.

Yay!