When I added an API Key mine APII on Portals is failing

Not applicable

Hi Community,

I am using Verify API Key Policy and everything is working if I made a request using curl.

e.g.:

curl -X GET "https://myapi.net/api/v1/resource/id" -H  "accept: application/fhir+json" -H  "x-api-key: apikey"

And for this request I can see on Apigee trace tool the follow headers :

Request Received from Client

GET /api/v1/resource/id

Request Headers

accept application/fhir+json
Host myapi.net
User-Agent curl/7.47.0
x-api-key apikey
X-Forwarded-For xxx.xxx.xxx.xxx
X-Forwarded-Port 443
X-Forwarded-Proto https

However when I make the same request from my api using Portals it's not working. I'm using a swagger:

From this request I got the follow on trace:

Request Received from Client

OPTIONS /api/v1/resource/id

Request Headers

Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip,deflate,br
Accept-Language en-US,en;q=0.5
Access-Control-Request-Headers x-api-key
Access-Control-Request-Method GET
Host myapi.net
Origin https://developers.portal.net
User-Agent Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0
X-Forwarded-For xxx.xxx.xxx.xxx
X-Forwarded-Port 443
X-Forwarded-Proto https


I've tested the same swagger yaml file using swaggerhub.com to make the request and from there its working fine.

From trace and making the request using swaggerhub.com I've got the follow:

Request Received from Client

GET /api/v1/resource/id

Response Sent to Client

200

Request Headers

Response Headers

accept application/json
accept-encoding gzip,deflate,br
accept-language en-US,en;q=0.5
Content-Length 0
Host myapi.net
if-none-match W/"OFqI5mfTK+p+0KxTJX+PZw=="
referer https://app.swaggerhub.com/apis/myapi/api-dev/1.0
user-agent Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0
x-amzn-trace-id Root=1-5aa105c4-91f63b2e3804baf0c111579e
x-api-key apikey
X-Forwarded-For xxx.xxx.xxx.xxx,
xxx.xxx.xxx.xxx,

xxx.xxx.xxx.xxx

X-Forwarded-Port 443
X-Forwarded-Proto https

I've noticed that when I made the request from curl, and swaggerhub I can see the x-api-key header on request but not by portals.

Thanks in advance if you can help me. And if you need more details, please just ask. Let me know if you guys need me to paste some xml configuration from my proxy api.

Thank you

0 1 210
1 REPLY 1

yes, this is a CORS issue. Thanks for the detailed explanation, very helpful.

You wrote:

when I make the same request from my api using Portals it's not working.

If you invoke the API from the API Portal, the BROWSER follows something called the "same origin policy", which says that requests made from JavaScript running inside the browser can to be sent back only to the origin that served the webpage. If you load your browser page from "myportal.developers.net" then the JS in the browser can make a request back to "myportal.developers,net" but cannot make a request to "www.google.com" or to "myapi-test.apigee.net".

This policy was instituted to prevent cross-site scripting issues. It was viewed as overly restrictive, and so browser makers created a system by which browsers would request access to external sites via something called CORS.

As part of the CORS mechanism, before a browser can send a GET with a header like x-api-key, the browser will send an OPTIONS request. (In case you were not aware, OPTIONS is another HTTP verb, designed for this kind of thing). This is known as the "CORS Pre-flight request".

The web server (in this case, the Apigee-hosted API endpoint) receives the OPTIONS request and needs to respond in a certain way, for the browser to allow the original GET request to go through. If all you see is OPTIONS in the Apigee Trace, then you can conclude that the API Proxy did not respond with the correct CORS response.

Therefore the browser "gives up" and doesn't send the GET.

Why is it working from "Swaggerhub"? Well probably because the request you send from the browser page on swaggerhub.com is being sent back to swaggerhub.com, and then that server is sending it along to your API endpoint. In other words, swagger hub is acting like a relay. The Same-origin policy does not apply to calls made outside a browser, so that calls made from a command line with curl, or calls made from one server to another, will not be restricted.

How can you modify your proxy to handle CORS correctly?

For that, see this old answer from the archives !