noirbizarre / flask-restplus

Fully featured framework for fast, easy and documented API development with Flask
http://flask-restplus.readthedocs.org
Other
2.74k stars 506 forks source link

Making swagger docs function behind reverse proxy #310

Closed atoy3731 closed 5 years ago

atoy3731 commented 7 years ago

I'm having some issues with trying to get the Swagger docs to work behind a reverse proxy. I have a microservice infrastructure, and am using NGINX to proxy to each service based on a location block. Here's a simplified service:

from flask import Flask
from flask_cors import CORS
from flask_restplus import Api, Resource
from werkzeug.contrib.fixers import ProxyFix

application = Flask(__name__)

application.wsgi_app = ProxyFix(application.wsgi_app)

api = Api(
    application,
    title='Test Microservice',
    description="Test Microservice",
    default='test-service'
)

CORS(application)

@api.route('/ping')
class Ping(Resource):
    def get(self):
        return 'pong', 200, {'Content-Type': 'text/plain; charset=utf-8'}

if __name__ == "__main__":
    application.run(host='localhost', port=9090, debug=True, threaded=True)

This works fine in my IDE, but when going through NGINX, I end up with broken links. Here's my NGINX config:

upstream test-service {
  server localhost:9090;
}

server {
        listen 8282 default_server;
        server_name localhost;

        location /test-service/ {
                proxy_pass http://test-service/;
                proxy_redirect     off;

                proxy_set_header   Host             $host:$server_port/test-service;
                proxy_set_header   X-Real-IP        $remote_addr;
                proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }
}

The HTTP headers resolve getting the swagger.json file, but I still have 2 issues:

  1. The JS/CSS that Swagger provides still tries to retrieve it from the root URL (ie, http://localhost:8282/swaggerui/bower/swagger-ui/dist/css/reset.css). I've worked around this by actually hosting the JS/CSS on my NGINX box, so it truly is available at that URL. That's more of a bandaid though. I'd prefer to it to actual pass the location block of NGINX.

  2. Even with my UI working, the Try It Now functionality uses the root URL without the added location. For instance: http://localhost:8282/ping instead of http://localhost:8282/test-service/ping. Is there a way, via simple HTTP headers/configuration, to have it use the reverse proxy location block (/test-service/)?

ryan-bever commented 6 years ago

Have a look at this flask snippet and see if it can resolve your issue.

http://flask.pocoo.org/snippets/35/

ziirish commented 5 years ago

Hi,

I think this is a duplicate of #223

ziirish commented 5 years ago

I'm now closing this issue. Please follow discussions in #223