# Intercept every request from Kibana plugin

**URL:** <https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021>\
**Category:** Kibana\
**Created:** [April 21, 2020, 10:55am UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021 "2020-04-21T10:55:42Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Digl1](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/digl1/32/66794_2.png) [@Digl1](https://discuss.elastic.co/u/Digl1)\
**Post date:** [April 21, 2020, 10:55am UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/1 "2020-04-21T10:55:42Z")

</div>

Hi,  
I have tried a lot, but I can't really get it to work.  
I want to intercept all requests from kibana to elastic and modify the HTTP request Headers.  
I am also not sure what the correct approach to this would be - should I try to use kfetch?  
Or is the better approach $http (I think this is the old deprecated way)?  
If kfetch is the right way, how do I add it to my plugin (do I need to add it to package.json)?  
And how do I reference it in a .js file?

```auto
import { kfetch } from '../../../../src/legacy/ui/public/kfetch/';
module.exports = {
    init : function(){
        kfetch.interceptors.push({
            request: async function(config) {
                Logger.log("request intercepted")
                // do something with request
                return config;
            }
        });
    }
}

```

Doing it like this, I get:

> FATAL Error: Cannot find module 'ui/new\_platform'

If I import from 'ui/kfetch' I get the following error message:

> FATAL Error: Cannot find module 'ui/kfetch'

Please help me with this - I have gotten so far with my custom plugin and this is the last piece of the puzzle...  
(Kibana version 7.6.2)  
Thank you!

---

<div class="post-metadata">

**Author:** ![flash1293](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/flash1293/32/41227_2.png) [@flash1293](https://discuss.elastic.co/u/flash1293)\
**Post date:** [April 21, 2020, 12:40pm UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/2 "2020-04-21T12:40:03Z")

</div>

Both of them are deprecated and will be removed completely soon. To intercept requests, you should use the `http.intercept()`api of the core setup services.

If you are already in the new platform, it will be available on the `core` parameter of the setup lifecycle hook. If you are working with the legacy platform, it should be available via

```auto
import { npSetup } from 'ui/new_platform';

npSetup.core.http.intercept({/...

```

---

<div class="post-metadata">

**Author:** ![Digl1](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/digl1/32/66794_2.png) [@Digl1](https://discuss.elastic.co/u/Digl1)\
**Post date:** [April 21, 2020, 12:57pm UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/3 "2020-04-21T12:57:57Z")

</div>

Hi, Thanks for your response!  
could you give me a complete example on how to achieve the modification of a http header?

When I use npSetup I get the following error message:

> Cannot read property 'http' of null

Thanks in advance!

---

<div class="post-metadata">

**Author:** ![flash1293](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/flash1293/32/41227_2.png) [@flash1293](https://discuss.elastic.co/u/flash1293)\
**Post date:** [April 21, 2020, 1:20pm UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/4 "2020-04-21T13:20:14Z")

</div>

The interface should be the same as the kfetch code in the original post: [https://github.com/elastic/kibana/blob/master/docs/development/core/public/kibana-plugin-core-public.httpinterceptor.md](https://github.com/elastic/kibana/blob/master/docs/development/core/public/kibana-plugin-core-public.httpinterceptor.md)

---

<div class="post-metadata">

**Author:** ![flash1293](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/flash1293/32/41227_2.png) [@flash1293](https://discuss.elastic.co/u/flash1293)\
**Post date:** [April 21, 2020, 1:22pm UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/5 "2020-04-21T13:22:00Z")

</div>

It seems like your plugin is not set up the right way and the new platform is not available. Can you share either your plugin code or a minimal reproducable example?

---

<div class="post-metadata">

**Author:** ![Digl1](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/digl1/32/66794_2.png) [@Digl1](https://discuss.elastic.co/u/Digl1)\
**Post date:** [April 21, 2020, 1:22pm UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/6 "2020-04-21T13:22:09Z")

</div>

This is what I got now:  
Index.js:

```auto
      import { npSetup } from '../../src/legacy/ui/public/new_platform';
      ...
      npSetup.core.http.intercept(new CustomHttpInterceptor);

```

CustomHttpInterceptor.ts:

```auto
import { HttpInterceptor, HttpFetchOptions, HttpFetchOptionsWithPath, IHttpInterceptController } from '../../../../src/core/public';

export class CustomHttpInterceptor implements HttpInterceptor {
  constructor() {}

  request(
    fetchOptions: Readonly<HttpFetchOptionsWithPath>,
    controller: IHttpInterceptController
  ) {
    //CHANGE HEADER HERE?
  }
}

```

this results in the above mentioned error...

---

<div class="post-metadata">

**Author:** ![Digl1](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/digl1/32/66794_2.png) [@Digl1](https://discuss.elastic.co/u/Digl1)\
**Post date:** [April 21, 2020, 1:23pm UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/7 "2020-04-21T13:23:03Z")

</div>

I used the scripts/generate\_plugin.js script to generate the plugin

---

<div class="post-metadata">

**Author:** ![flash1293](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/flash1293/32/41227_2.png) [@flash1293](https://discuss.elastic.co/u/flash1293)\
**Post date:** [April 21, 2020, 1:29pm UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/8 "2020-04-21T13:29:03Z")

</div>

When you are using the generator, then it will set up a new platform plugin for you and you can get the reference to the http service in the `setup` method of your plugin class (`core.http.intercept`).

Not sure what exactly `index.js` is referring to, this is not a file generated by the script.

Please share either your plugin or if that's not possible a minimal reproducable example of what you are trying to do, this makes helping you much simpler.

---

<div class="post-metadata">

**Author:** ![Digl1](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/digl1/32/66794_2.png) [@Digl1](https://discuss.elastic.co/u/Digl1)\
**Post date:** [April 21, 2020, 1:35pm UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/9 "2020-04-21T13:35:08Z")

</div>

When I use the generator script I get the following directory structure:  
README.md  
index.js  
node\_modules/  
package.json  
public/   
server/   
yarn.lock

> [@flash1293](#):
>
> setup

Do you mean the init() function in the index.js

---

<div class="post-metadata">

**Author:** ![Digl1](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/digl1/32/66794_2.png) [@Digl1](https://discuss.elastic.co/u/Digl1)\
**Post date:** [April 21, 2020, 2:21pm UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/10 "2020-04-21T14:21:05Z")

</div>

Am I missing something here?  
Looks like my plugin is not generated correctly...  
☹

---

<div class="post-metadata">

**Author:** ![flash1293](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/flash1293/32/41227_2.png) [@flash1293](https://discuss.elastic.co/u/flash1293)\
**Post date:** [April 21, 2020, 2:25pm UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/11 "2020-04-21T14:25:05Z")

</div>

Ah, I was looking at the wrong plugin generator, my bad.

To intercept the requests going from Kibana client to Kibana server, you have to do this in the `hacks.js` in the public folder - the `index.js` file is executed on the server, but these APIs are client-side APIs.

Then make sure to whitelist the header so it's passed through to Elasticsearch (`elasticsearch.requestHeadersWhitelist` in `kibana.yml`).

---

<div class="post-metadata">

**Author:** ![Digl1](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/digl1/32/66794_2.png) [@Digl1](https://discuss.elastic.co/u/Digl1)\
**Post date:** [April 21, 2020, 2:28pm UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/12 "2020-04-21T14:28:50Z")

</div>

Ahh ok, thanks!  
So how would I rewrite the headers in the hacks.js?  
Should I just set the default ajax header like this:

```auto
$.ajaxSetup({
    beforeSend: function (xhr)
    {
       xhr.setRequestHeader("SomeHeader","SomeValue");

    }
});

```

or

```auto
XMLHttpRequest.prototype.origOpen = XMLHttpRequest.prototype.open;
        XMLHttpRequest.prototype.open = function () {
            this.origOpen.apply(this, arguments);
            this.setRequestHeader('SomeHeader', 'SomeValue');
        };

```

Or is there a more "Kibana"-way to do it?

Kind Regards!

---

<div class="post-metadata">

**Author:** ![flash1293](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/flash1293/32/41227_2.png) [@flash1293](https://discuss.elastic.co/u/flash1293)\
**Post date:** [April 21, 2020, 2:38pm UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/13 "2020-04-21T14:38:41Z")

</div>

The rest with `CustomHttpInterceptor` and

```auto
import { npSetup } from 'ui/new_platform';

npSetup.core.http.intercept({/...

```

should work in there.

In the `request` function of the interceptor you should be able to add it to the `headers` property of the first parameter.

---

<div class="post-metadata">

**Author:** ![Digl1](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/digl1/32/66794_2.png) [@Digl1](https://discuss.elastic.co/u/Digl1)\
**Post date:** [April 21, 2020, 2:39pm UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/14 "2020-04-21T14:39:28Z")

</div>

I'll give that a try, thanks!

---

<div class="post-metadata">

**Author:** ![Digl1](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/digl1/32/66794_2.png) [@Digl1](https://discuss.elastic.co/u/Digl1)\
**Post date:** [April 21, 2020, 2:46pm UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/15 "2020-04-21T14:46:46Z")

</div>

Sorry if I'm asking too much, I'm almost done (I hope) 😛  
So in my HTTPInterceptor I have the following:

```auto
request( fetchOptions: Readonly<HttpFetchOptionsWithPath>, controller: IHttpInterceptController) {
    // add header here
}

```

the constructor tells me readonly, how would I add the headers here?  
Thank you!!

---

<div class="post-metadata">

**Author:** ![flash1293](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/flash1293/32/41227_2.png) [@flash1293](https://discuss.elastic.co/u/flash1293)\
**Post date:** [April 21, 2020, 3:45pm UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/16 "2020-04-21T15:45:28Z")

</div>

I checked and you are right, but this type is just a type - it's not enforced. I tried this:

```auto
        (fetchOptions as any).headers = {
          ...(fetchOptions.headers || {}),
          'my-custom-header': 'abc',
        };

```

and it works fine (the header is added to the request).

So it is a way to do things, but it's not guaranteed this works in every scenario or in the next version because it's basically a hack. In that case monkey-patching the XMLHttpRequest class (like you are doing above) is probably also a good approach, but it might break in other ways.

I don't think there is another official "Kibana"-way to do this, I guess this case didn't pop up before.

---

<div class="post-metadata">

**Author:** ![Digl1](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/digl1/32/66794_2.png) [@Digl1](https://discuss.elastic.co/u/Digl1)\
**Post date:** [April 21, 2020, 8:21pm UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/17 "2020-04-21T20:21:23Z")

</div>

I used Wireshark to inspect traffic between kibana and elastic, but could only find the header in the requests made from the xhr setRequestHeader.

I need the custom Header in every request to elasticsearch (also from server side requests)  
☹

Can you think of a better way to intercept traffic and add a http header between kibana and elasticsearch?  
It doesn't necessarily need to be a plugin...  
Thanks!

---

<div class="post-metadata">

**Author:** ![Digl1](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/digl1/32/66794_2.png) [@Digl1](https://discuss.elastic.co/u/Digl1)\
**Post date:** [April 21, 2020, 8:54pm UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/18 "2020-04-21T20:54:20Z")

</div>

> [@flash1293](#):
>
> (fetchOptions as any).headers = { ...(fetchOptions.headers || {}), 'my-custom-header': 'abc', };

Using this code, I get the error message in the browser console:

> TypeError: Cannot assign to read only property 'headers' of object '#\<Request\>'

I can't post another reply, because I am a new User...  
Hi!  
I did that add the header to the kibana.yml:

> elasticsearch.requestHeadersWhitelist: [test]

hack.js:

```auto
const interceptor = new CustomHttpInterceptor();
npSetup.core.http.intercept(interceptor);

```

```auto
export class CutstomHttpInterceptor implements HttpInterceptor {
  constructor() {}
  request(fetchOptions: Readonly<HttpFetchOptionsWithPath>, controller: IHttpInterceptController) {
    console.log('----------------------------------------------');
    console.log(fetchOptions.headers);
    (fetchOptions as any).headers = {
      ...(fetchOptions.headers || {}),
      'test': 'LALALALALA',
    };
  }
}

```

Still getting:

> Cannot assign to read only property 'headers' of object '#\<Request\>'

Yet another reply as edit:  
Ah ok, sorry!  
It works this way (Xmlhttprequest monkey patching) with ui originated requests (from browser).

If I would want to edit the kibana src code, is there a single file/directory where all the requests to elastic are handled?

Thanks for all your help!

---

<div class="post-metadata">

**Author:** ![flash1293](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/flash1293/32/41227_2.png) [@flash1293](https://discuss.elastic.co/u/flash1293)\
**Post date:** [April 22, 2020, 2:57am UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/19 "2020-04-22T02:57:23Z")

</div>

See the second part of my post from above, you also have to set the header name in the respective kibana.yml file setting:

> [@flash1293](#):
>
> Then make sure to whitelist the header so it's passed through to Elasticsearch `elasticsearch.requestHeadersWhitelist` in `kibana.yml`

There are some requests this wouldn’t work for, though (because the Kibana server is also making requests on its own not directly coming from the client).

If the value of the header is static, you can also simply use the “elasticsearch.customHeaders” setting in Kibana.yml

If it has to be dynamic and for every single request sent to Elasticsearch, then I think there is currently no way to do this without changing the source code of Kibana itself (basically forking it).

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [May 20, 2020, 2:57am UTC](https://discuss.elastic.co/t/intercept-every-request-from-kibana-plugin/229021/20 "2020-05-20T02:57:29Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
