CORS Confusion - SwaggerUI and multiple 'Access-Control-Allow-Origin' headers

2,721 views
Skip to first unread message

Erica Findley

unread,
Aug 3, 2016, 4:06:06 PM8/3/16
to Swagger
I have been battling a CORS issue for a few days and I'm hoping someone here will have the know-how to help me work through it.  
The scenario: I have swagger UI hosted on a site that will then be accessing the swagger.json documents for various services running on various servers.  All of these services and API calls are routed through an API-gateway, but the swagger UI is not.  All the projects are java/Spring based.  The API-gateway is a Zuul application and the rest endpoint is Spring/JAXRS.  Both the gateway and the service have a Filter to add the CORS headers. 
The current flow: 
  • swagger UI pulls up the swagger.json document through the gateway (it actually uses an authorization header to allow passage through the gateway -- this works fine)
  • Use a "Try it now" button on a simple API endpoint
  • The request goes through the gateway and down to the service
  • The service endpoint is hit and the proper response values generated (I can debug this and see the values being set)
  • when the UI renders the result, I get a 200 response but with no response content.
  • In the chrome dev-tools console, there is a message saying: XMLHttpRequest cannot load <api-gateway>/<api-endpoint>. The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed. Origin '<swagger-UI-URL>' is therefore not allowed access.
Sure enough, I check the response headers using the browser dev-tools and  'Access-Control-Allow-Origin' is there twice.  The confusing part is this:  If I take the CURL statement that the swagger UI generates and run it directly in a terminal, the request works fine.  And a `curl -I` shows only one 'Access-Control-Allow-Origin' header like it should.  I thought that it might be the fact that both the gateway and the API service have a CORS Filter, and yes, when I disable one of them, I only get one header.  But if that were the only problem, wouldn't I see two headers when I ran a simple curl check? What is it that the swagger UI is doing that would mean it ends up with two headers? It is only the SwaggerUI that is highlighting the problem.  Any other attempt to access the services and the CORS headers work properly. 

Does anyone have any ideas that could point me towards a solution? 

Thanks!

tony tam

unread,
Aug 3, 2016, 4:12:16 PM8/3/16
to swagger-sw...@googlegroups.com
Hi,
CORS is a really painful thing to deal with.  The browser is quite picky about respecting CORS constraints for your own safety.

When you use CURL, it does not care about CORS so it doesn’t need to honor anything.  But it is true that having multiple Access-Control-Allow-Origin headers is illegal and probably is a bug of your gateway.

Fixing that may be hard.  One option is to remove the header from your application, so your Gateway will only add one.  But that in itself is a really awful hack.

When performing the preflight check, your browser (not swagger-ui, to be clear) will ensure that it is allowed to POST by performing the preflight check against the service that you want to call.  Thus, it doesn’t matter what the server said about the swagger definition—the important part is what is said about the resource you’re calling


--
You received this message because you are subscribed to the Google Groups "Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Erica Findley

unread,
Aug 3, 2016, 4:22:22 PM8/3/16
to Swagger
Yes, it's been very painful!! :) I realized that I'm not sure if I was completely clear on something. Yes, I can see both the pre-flight OPTIONS call and the actual GET call to the endpoint in the browser dev tools when I click the try-it-now button.  
But also, if the pre-flight failed completely, wouldn't that mean that the request would never be made to the API-endpoint?  Instead, the behavior that I'm seeing is that the endpoint is being hit (I can trace the call through the logs and also through remote debugging sessions) and then it returns as if everything is fine (from the perspective of the server-side API-endpoint).  But when the swagger-UI renders the response results, I get no-content. The swaggerUI shows a response code of 0, but the chrome dev tools shows a response code of 200. I don't know why the difference. 

And I just noticed, in the OPTIONS check the response only has one origin header, but in the actual GET, the duplication occurs.
Reply all
Reply to author
Forward
0 new messages