Using OpenSearch dashboard inside React IFrame
Intro
If you are anxious, just jump to the solution
AWS OpenSearch service is an ElasticSearch and Kibana (based on). You can deploy it as serverless (it's in preview when writing this post) or as another AWS service. You can secure it with Cognito service (really recommend this). It's a easy service to deploy, but some issues may come when you try to do somethin so "simple" as including a kibana dashboard inside an IFrame (using React/Angular/Vue makes this a little easier). But, the implementation is not strightforward, AWS doesn't have documentation on this (only on how to include a reverse proxy behind OpenSearch)and I've not seen anyone trying this (or at least creating some post/article about this topic). So, this post is trying to make your life easier if you have to include a dashboard inside an iframe (without logging inside your app and iframe, if you can).
What's the problem?
The main problem is that for doing this, you will be facing many HTTP and OAUTH2 challenges (headers, cookies, domains). And AWS doesn't allow by default to do this. So you have to be a little creative to make this work.
I recommend that you read how OAUTH2 works and how HTTP works (headers, cookies), as I'm not covering this on this post. I will just go over a quick refresh
OAUTH2 flow
When the user wants to login
- App (browser) redirects the user to authserver (ex: cognito) to the
<AuthServer>/login
endpoint indicating that the login flow iscode
(response_type=code). It also includes theclient_id
andredirect_uri
on the request - AuthServer shows the login page
- The user types username and password and clicks on login
- AuthServers validates username and password, if it's ok, redirects the browser to the
redirect_uri
(step 1) including a one timecode
in the URL. Something like `<redirect_uri>?code= - The App (Ex: React) reads the code and ask the AuthServer for the tokens (doing a POST request to
<AuthServer>/oauth2/token
including the code and some extra information. - The AuthServer returns a JSON response including
access_token
,id_token
,refresh_token
. The most important token for us is theaccess_token
that will allow us to do HTTP request to a server that requires authentication. - In each request that the App makes to the Server, it includes the
access_token
. Including anAuthorization: JWT access_token
in each request header.
OpenSearch dashboard login flow
The login process is similar to the previous one. The most important difference is that the previous flow uses a JWT token in the request, while this flow uses cookies. Why? because the first the request are made by an app that can manage the headers to include the JWT token, while the second the requests are made by the browser, without an App intervention (so cookies fits better here).
When you should use Tokens and when Cookies?
Tokens
You are developing an App and that App is the one that makes requests to the backend. Is the most common way of authentication when you are developing an App that runs on the browser (React, Angular, Vue, Vanilla JS)
Cookies
The user interacts directly with a third party app or backend. It was really popular in the past when the backend was an MVC that returned pages.
And the problem is...
If you try to include an OpenSearch dashboard inside an IFrame using your previously cognito authentication, you will have to login twice (one from your browser App, and one inside your IFrame). To avoid this, we will have to make some changes to the whole flow, including a Reverse Proxy to manage the conversion from Body response tokens to cookies and changing some response headers to allow IFrames (and proxy all requests to cognito and opensearch).
My solution
How this work?
I've included a Reverse Proxy (NGINX) between the App and Cognito/OpenSearch to keep the same domain and develop a small NGINX JS script to fetch the token and convert it to cookies (feel free to use an external server to do the same).
We need both the cookies and tokens to this to work. The App needs the token to create the Authorization: JWT token
requests. And the IFrame needs to send cookies to OpenSearch (using the Reverse Proxy as the server, then NGINX proxies the request to opensearch).
The use of the NGINX is important to maintain the same domain and manipulate the cookies/responses consistent with the OpenSearch requirements.