Said Swagger UI: Browser, I need to CORS. What OPTIONS do I have?
Lately I’ve been working on a project where we have the chance to develop swagger documentation. It’s a dedicated instance, not our SaaS. It’s great! When the documentation is in good shape, it’s easy to try out the API from web UI. Except that it doesn’t always work (It’s that “Failed to fetch” bit):
Ok, so what to do? We tried out a few things, searched the internets and noticed a few things. There is this thing called CORS which stands for Cross Origin Resource Sharing. The page where swagger documentation is shown is fetched from our servers, but the swagger UI also needs to make calls to the server where the REST API is. This is a potential security risk, so browser wants to ask permission from the REST API server if it’s ok to use those resources (i.e. try out the API thru web UI swagger documentation)
If you want to make anything except a simple GET or there are any custom headers, the browser wants to make a preflight query to the back end. Browser wants to know if it’s ok to ask whatever it actually wants to ask. So the browser sends an OPTIONS method query to the back end passing along all the headers that the actual request will need. Sounds simple enough (yeah OK, it took me some time until I figured it out. I’m a bit slow) what can go wrong?
What could go wrong?
Well. 1st of all, API Umbrella (the proxy we are using) wants to have X-Api-key in the header. When browser sends the OPTIONS query, browser does not know that there needs to be X-Api-Key in the headers. When it’s not, the proxy responds politely “sorry, but this request is going nowhere without the X-Api-Key” -> fail.
2nd, backend has no idea that it would need to return X-Api-Key value in Access-Control-Allow-Headers. Without this, the browser will think that it’s not allowed to use that in the actual request and will not execute the query -> fail.
Solution Hack
How to get this working in our case? There are few ways to get this working. Excellent (long) explanation in issue 391
Here is the short answer: Configure API Umbrella. In this particular case we just decided that we overwrite the response headers to the OPTIONS query:
EDIT on 1.6.2018: and you also need to disable API key check:
Is this a good solution? It depends. If it is a dedicated instance like the one in question, this is a manageable work around. How ever, this needs proper fixing, and there is one planned. Details are in that issue 391 mentioned above, one idea would be to append the response headers instead of overriding them. Manifestation of this could be an additional field to the configuration screen depicted above.
There will always be problems, especially when you are creating something new. Together we will solve them.