Swagger behind Nginx Proxy and CORS error
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Swagger behind Nginx Proxy and CORS error
PS
I wonder if it is possible to make proxy + cors configured on swagger.example.com in such a way, that I do not have to add:
- Labels:
-
Swagger UI
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hey @Newbie1
It's a little hard to visualize what you're after. As you may know CORS is a browser thing, not a Swagger thing.
If you're referring to the Try-it-out feature of Swagger UI then CORS would need to be enabled on your API Server (or proxy), for those features that you'd like browser to be able to use. Alternatively if you're only interested in render SwaggerUI on different websites, then you should be able to get away with no CORS, or minimal configuration.
It is unfortunately a security you and your organization will need to decide on. If you enable CORS for all websites, it may be a security risk.
If you have question more related to Swagger, or if I've misunderstood feel free to shout.
A great resource for CORS is https://enable-cors.org/
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks a lot for the reply. I will describe more specifically on Friday as I currently have food poisoning. 🙂
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, I know CORS is a browser thing. Yes I am referring to "Try it out" feature of the Swagger UI. Currently I have few APIs on few servers. Each looks like t{1,2,3,4}.example.com/swagger. Inside vhost file config looks like
location /swagger {
root /home/deployuser;
}
where inside /home/deployuser is "swagger" directory deployed plain old html/css/js method described in the docs. Of course it works.
But now I my goal is different approach. I have an application based on "Sinatra" which includes Swagger UI (the same files like from "plain on deployment method"). This app is available under, lets say, docs.swagger.example.com. When I open docs.swagger.example.com and put credentials to authenticate Swagger UI opens. Then I can choose to which API (t{1,2,3,4}.example.com/api) I would like to send request. Here the problem with CORS appears. Nginx config of the docs.swagger.example.com: https://pastebin.com/0mpf7ve7. I tried to add the line --> add_header Access-Control-Allow-Origin "https://docs.swagger.example.com"; to the nginx config files of the t{1,2,3,4}.example.com APIs. It does not help. 😕
I stucked. Is it possible to resolve it on the server docs.swagger.example.com side like docs https://swagger.io/docs/open-source-tools/swagger-ui/usage/cors/ says in the point 2 - quote "The application is located behind a proxy that enables the required CORS headers."?
@ponelat Generally speaking which headers should I add to nginx config of the docs.swagger.example.com to resolve the cors issue?
PS
I tried many different configs found on the Internet but ..., among others below config which looks the best for me:
add_header Access-Control-Allow-Origin "*";
if ($http_origin ~* "^https://(t1.example.com|www.t1.example.com|t2.example.com|www.t2.example.com|and-so-on)$") {
add_header Access-Control-Allow-Origin "$http_origin";
}
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hey @Newbie1 ,
It's a little out of scope of Swagger UI, how you configure the server for CORS. All browser clients should behave in a similar fashion.
That said, you should be able to get far debugging the exact error messages that appear in the console. And using https://www.test-cors.org/ to help debug issues.
Console errors can look like his:
You'll note that https://example.com doesn't have a `Access-Control-Allow-Origin` header, in your case you may notice other errors.
Here is an nginx example: https://enable-cors.org/server_nginx.html
Assuming you want full access to the API via the browser, you'd need to use:
- Access-Control-Allow-Origin: <the exact host name> (wildcard * has limitations on Authorization). This is something you're doing though.
- Access-Control-Allow-Headers: GET,POST,PUT,etc
And you'll also need to accept OPTIONS request for preflight requests (the browser asks the server before making the actual request)
Hope that helps!
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I try this approach and let you know for 100%! 🙂
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@ponelat In my case it looks like this:
It's from Chrome. From firefox error from console is more accurate:
If you have any hints - appreciate! I am still trying resolve it.
PS
I also tried to copy paste config from this site https://enable-cors.org/server_nginx.html to swagger.example.com nginx config. Still nothing. Maybe something with proxy headers etc?
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Newbie1 I see the standard error, the response headers are missing:`Access-Control-Allow-Origin: docs.swagger.example.com` .
This was surmised from "CORS Missing Allow Origin" error.
Be sure to support an OPTION pre-flight requests as well as returning the `Access-Control-Allow-Origin: docs.swagger.example.com`.
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@ponelat Thank you for an answer. I add whole config from https://enable-cors.org/server_nginx.html to the nginx config of the t1.example.com:
add_header 'Access-Control-Allow-Origin' '*';
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
}
}
and now Chrome returns something like this:
and Firefox:
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Newbie1 That's addressed a CORS issue, since the error appears to be from the server (unregistered device doesn't sound like any browser/web api error).
To support Authorization headers, you need to change from `*` to an explicit origin. You can confirm by trying a hardcoded one, and if that works you can figure out how to make it dynamic (with nginx).
Replace all instances with this...
add_header Access-Control-Allow-Origin: 'docs.swagger.example.com' always;
