How to set CORS headers on public API

Options
AndresSilva
AndresSilva Registered Posts: 9 ✭✭✭✭

Hi!

I have created an API in Dataiku, with the endpoint being a Python Function.

I am able to call the API from python using both a) dataiku's dataikuapi, and b) using a plain HTTP requests.

However, due to some company policies, I'll have to call the API from Javascript, with a cross-origin request, and thus will need to setup a CORS header on the API.

Here it is mentioned that is is posible to do so in Dataiku. However I haven't found any additional documentation on that regard.

Could anyone please give me further information on how this would be done?

Thank you very much!

Best Answer

  • Andrey
    Andrey Dataiker Alumni Posts: 119 ✭✭✭✭✭✭✭
    edited July 17 Answer ✓
    Options

    Hi @AndresSilva
    ,

    Thanks for clarification, I can confirm that CORS filters are only available for the design node public API defined here:

    https://doc.dataiku.com/dss/api/8.0/rest/

    Since you're trying to reach the API node this feature is not available.

    However you may overcome this limitation by modifying the ./install-support/nginx.conf in the API node datadir.

    inside of it you'll find a section like

    location /public/ {
                proxy_pass http://127.0.0.1:11811/public/;
            }

    so next to it you paste the following code:

    set $cors '';
            if ($http_origin ~ '.*') {
                set $cors 'true';
            }
    
    
            location /public-cors/ {
                if ($cors = 'true') {
                    add_header 'Access-Control-Allow-Origin' "$http_origin" always;
                    add_header 'Access-Control-Allow-Credentials' 'true' always;
                    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
                    add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;
                }
    
                if ($request_method = 'OPTIONS') {
                    add_header 'Access-Control-Allow-Origin' "$http_origin" always;
                    add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;
    
                    add_header 'Access-Control-Max-Age' 1728000;
                    add_header 'Content-Type' 'text/plain charset=UTF-8';
                    add_header 'Content-Length' 0;
                    return 204;
                }
                proxy_pass http://127.0.0.1:11811/public/;
            }

    of course, the port 11811 should be modified to match whatever you have in your config. Also I'm using the pattern that matches all of the http origins (.*) you may want to restrict it.

    After doing that and restarting DSS, in addition to the standard /public/* endpoints you'll also get a /public-cors/* that will add the CORS headers to the responses

    Regards

Answers

  • Andrey
    Andrey Dataiker Alumni Posts: 119 ✭✭✭✭✭✭✭
    Options

    Hi @AndresSilva
    ,

    Public API CORS headers are available under Administration -> Misc -> Public API CORS headers

    Regards,

  • AndresSilva
    AndresSilva Registered Posts: 9 ✭✭✭✭
    edited July 17
    Options

    @Andrey
    , thank you very much for your help.

    We just tried it but unfortunately, with no luck. Maybe if I share with you additional information you could help us.

    We are setting up a web app in Dataiku. In it we are launching a request to an API on the same project.

    The Api is working correctly (we have called it from Python and it works as expected).

    In our web app, we are calling the Api with the following code:

    function dataikuREST() {
        url = 'apiNodeIP_And_Port/public/api/v1/Service_ID/Endpoint/run/?var1=SOMETHING'
        var apiKey = 'ourApiKey';
        // We use fetch API (https://developer.mozilla.org/fr/docs/Web/API/Fetch_API/Using_Fetch)
        fetch(url, {
            headers: {
                'Authorization': 'Basic ' + btoa(apiKey + ':' + '')
            }
        })
        .then(response => {
            if (response.ok) {
                    response.json().then(
                        result => console.log("Success")
                    );
                } else {
                    response.json().then(
                        err => console.log(err.message)
                    );
                }
        });
    }

    (Note: The same get requests works ok in Python.)

    However, our DesignNode server is different from our AppiNode server, thus, we are getting this error:

    Access to fetch at 'apiNodeIP_And_Port/public/api/v1/Service_ID/Endpoint/run/?var1=SOMETHING' from origin 'http://designNodeIP' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

    Thanks to your help we then went into 'Administration -> Misc -> Public API CORS headers' and tried to set it up, as follows:

    CORS headers.png

    (Note: We are trying with '*' first, just to get it to work. Then we would change it back to the DesignNode IP).

    However, we are still getting the same 'http://designNodeIP' has been blocked by CORS policy' error.

    Any ideas?

    Thank you very much!

  • rafael_rosado97
    rafael_rosado97 Partner, Dataiku DSS Core Designer, Dataiku DSS ML Practitioner, Dataiku DSS Adv Designer, Registered Posts: 58 Partner
    Options

    Hello, @Andrey

    I remember that I had the same problem. I set the same parameters but it did not work.
    Should I make any other configuration, for example, on CentOs etc/nginx/nginx.conf file?

    Thanks!!

  • Turribeach
    Turribeach Dataiku DSS Core Designer, Neuron, Dataiku DSS Adv Designer, Registered, Neuron 2023 Posts: 1,728 Neuron
    Options

    Rafael please start a new thread. This old thread is from 2020 and has been solved already.

  • rafael_rosado97
    rafael_rosado97 Partner, Dataiku DSS Core Designer, Dataiku DSS ML Practitioner, Dataiku DSS Adv Designer, Registered Posts: 58 Partner
    Options

    Thank you, @Turribeach
    .
    I already posted it here

Setup Info
    Tags
      Help me…