Metabase API to GET a questions data as json getting "CORS Policy - No 'Access-Control-Allow-Origin' "

I am trying to get raw data from a question by passing this Login | HSTS Redirection Community to axios.get() in my app. But I am getting an error:

has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource

When I put that url into a browser, I can download my data in raw JSON but can't seem to be able to consume that raw JSON data using axios or any library alike. Is this even possible ? I tried passing a header to my axios.get(). Like this

let axiosConfig = {
    headers: {
        "Content-Type": "Content-Type: application/json",
        "X-Metabase-Session": "id",
        "Access-Control-Allow-Origin": "*",
    }
}

axios.get('https://<site>.com/api/public/card/<token>/query/json', axiosConfig).then((res) => {
        console.log(res);
    })

Any help would be greatly appreciated!

1 Like

Hi @max1888

So this is probably because the request is coming from a different domain than where Metabase is hosted, which is blocked by CSP.
CORS are response header from the server - not request header.

I’m assuming that your script is located on www.example.com and Metabase on metabase.example.com - ?
Then you would need to either modify the source to change CSP and/or CORS - or you could use a reverse proxy to modify the headers.

CORS: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
CSP: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

Hi @flamber, thanks for the quick response. That is correct! My Metabase instance is running in AWS and my app in another domain. Is there any tutorial or similar question that sets this up for Metabase? I have no experience setting CORS and CPS.

Thanks again for your response.

That depends on which reverse proxy you’re using, but if Nginx, then this would probably be useful:
https://blog.confirm.ch/adding-and-removing-nginx-response-headers/

Hey @flamber, I am not using Nginx but just went with the recommended step of adding a load balancer in AWS to terminate in https. Any ideas how I would set this up in AWS?

@max1888
I don’t use AWS, but I’m guessing you’re using EB, which is in the documentation:

Right! I followed that documentation to set up Metabase but did not find anything about CORS in it. The only thing that is remotely close is setting up the NGINX server name, which i did. Any other helpful tip would be greatly appreciated.

But then you’re using a pre-built container, which already have a reverse proxy inside (which is actually Nginx).
You would need to run your own reverse proxy, because you want to change core security configuration.

Hi, i am facing the CORS issue as well when trying to access the API from different domain.

I am using the pre-built container which start directly from the docker command:
docker run -d -p 3000:3000 --name metabase metabase/metabase

Do you have any advice for me on how can i resolve the CORS issue?
I understand that I can solve it by adding Access-Control-Allow-Origin header in the nginx. However I cannot find my way to ssh into the nginx inside this docker image. In fact i don’t even know if the image come default with the nginx since you mention that “need to run your own reverse proxy”.

Thanks in advance

@tienping Sounds like you haven’t set your domain in Admin > Settings > General.
The official Docker image does not come with a reverse-proxy - the EBS image does, to get around how AWS works.
If you’re using Nginx, then you can likely find better help in a forum specific to that web-server or stackoverflow.com, since it’s not specific to Metabase.

For update, I check in the general setting and do not see domain setting. However, there is a “SITE URL” setting and apparently my colleague already set it to the url that I am always using.

So we found a workaround for the reverse-proxy using AWS services.
In a nutshell, we setup a API gateway with lambda proxy integration and a Lambda function which will do a http call and then append “Access-Control-Allow-Origin” header in the response.

Notes: We have tried with API gateway with http directly but the response do no contain the header, so we will have to use lambda to add the header before return the response.