Skip to content
This repository has been archived by the owner on Aug 4, 2023. It is now read-only.

How to run swagger-ui middleware behind a reverse proxy? #342

Closed
Nepoxx opened this issue Feb 5, 2016 · 19 comments
Closed

How to run swagger-ui middleware behind a reverse proxy? #342

Nepoxx opened this issue Feb 5, 2016 · 19 comments

Comments

@Nepoxx
Copy link

Nepoxx commented Feb 5, 2016

The way my app is set-up, I have Nginx serving a reverse proxy pointing to my app container in a docker.

I have http://services.mydomain.com/myservice point to the myservice docker. A GET request at http://services.mydomain.com/myservice/hello will look like GET /hello to my service, not GET /myservice/hello, so my basePath should be /.

If I set my basePath to that in my swagger document, however, swaggerUI will not send the requests correctly, even if I set the options to apiDocsPrefix: '/myservice', swaggerUiPrefix: '/myservice'. It will be able to correctly fetch the api-docs, but will make requests to http://services.mydomain.com/ and not http://services.mydomain.com/myservice/.

If I set my basePath to /myservice, swaggerUi will correctly make the requests, but swagger-router will not serve them (because it doesn't know about the reverse proxy).

Is there a way to make this set-up work?

@whitlockjc
Copy link
Member

Have you tried options.swaggerUiPrefix for the swagger-ui middleware? https://github.com/apigee-127/swagger-tools/blob/master/docs/Middleware.md#swaggeruioptions

@Nepoxx
Copy link
Author

Nepoxx commented Feb 5, 2016

I have, however that only makes swagger-ui work (accessible), but it won't send the requests to the right URL because it uses Swagger's basePath to do that, which swagger-router also uses to route requests.

@whitlockjc
Copy link
Member

Have you tried a recent release? There was a issue/PR for this that was fixed in 0.9.10.

@Nepoxx
Copy link
Author

Nepoxx commented Feb 5, 2016

I'm on 0.9.11

I'm looking into swagger-router and I'm not sure how this could possibly work right now.

Swagger-router uses the swagger document basePath to serve requests, which swagger-ui also does. However, when behind a reverse proxy, the paths do not appear the same to the application and swagger-ui.

@whitlockjc
Copy link
Member

I thought #317 would fix #297 which seems to be similar to this but maybe it didn't. I'm not sure how swagger-router is coming into the mix as it is not involved in the serving of swagger-ui. Are you saying API requests aren't matching properly? It seemed like you were saying that the swagger-ui API calls were failing to call the correct endpoint.

@Nepoxx
Copy link
Author

Nepoxx commented Feb 5, 2016

Are you saying API requests aren't matching properly?

Well, sort of.

Assuming I have a reverse proxy from http://www.mytopleveldomain.com/myapp -> my app

Let's say my swagger document looks like this (yaml):

basePath: /myBasePath
paths:
  /hello:
    x-swagger-router-controller: myCtrl
    get:
      operationId: helloWorld

and

myCtrl.helloWorld = function (req, res, next) {
  res.end('world');
}

With this set-up, swagger-router will only route GET /myBasePath/hello to myCtrl.helloWorld but due to the reverse proxy, a GET request to http://www.mytopleveldomain.com/myapp/hello will appear as GET /hello to my app, which will not get routed to myCtrl.helloWorld

@whitlockjc
Copy link
Member

In your case, I'd expect the basePath to be / instead of /myapp. Does that work?

@Nepoxx
Copy link
Author

Nepoxx commented Feb 5, 2016

If I do that, swagger-router is happy, but not swagger-ui. If my basepath is / and I use swagger-ui to make a GET /hello request, it'll make a request to http://www.mytopleveldomain.com/hello instead of http://www.mytopleveldomain.com/myapp/hello

My current workaround (and it might be the best solution) is to have my reverse proxy point to /myapp instead of / and set my basePath as /myapp.

Thanks for looking into this!

@Nepoxx Nepoxx closed this as completed Feb 5, 2016
@whitlockjc
Copy link
Member

I think you should make Swagger happy and if there is a bug in the swagger-ui middleware, we fix it. I think a basePath: / makes sense because your application is only interested in paths behind the proxy and is not proxy path aware. So if swagger-ui needs tweaking to work better behind a proxy, we can fix this.

@fredtma
Copy link

fredtma commented Nov 30, 2016

I am facing the same dilemma as @Nepoxx
Has there been any solution to this?

@Nepoxx
Copy link
Author

Nepoxx commented Nov 30, 2016

I've modified swagger-ui to support a specific basepath told the swagger-ui middleware to use my custom made swagger ui.

@fredtma
Copy link

fredtma commented Dec 1, 2016

I did not want to change swagger-ui client, since it is a node module.
My solution has been to server two swagger definition.
one that the swagger-tools will consume.

let spec = require('./api/swagger/swagger.json');
swaggerTools.initializeMiddleware(spec, function(middleware) {...});

Another base on the first which swagger-ui will consume, with a different basePath.

let specClone = _.cloneDeep(spec);
specClone.basePath = '/newlocation';

Note: do not use the swaggerUi middleware that initializeMiddleware provides,
because you need to pass the second definition.

swaggerTools.initializeMiddleware(swaggerDoc, function(middleware) {
app.use(middleware.swaggerMetadata());
//app.use(middleware.swaggerUi(wealthConfig('swaggerSetting'))); not this mw
let swaggerUi = require('./node_modules/swagger-tools/middleware/swagger-ui');
app.use(swaggerUi(sepcClone, {swaggerUiPrefix: '/newlocation'}));
}

@whitlockjc
Copy link
Member

Altering swagger-ui is something we expect you to need/want to do. As with much of the swagger-tools middleware, we include a lot out of the box to make things as simple as possible to get up and running. But at some point, like this, it might be simpler to just provide your own swagger-ui distribution and use the provided options to wire in your own swagger-ui.

I'll see if I can get some documentation published on taking this approach.

@brunobertechini
Copy link

Ok So i faced same issue and would like to know what should I do (im using AspNEtCore with Swagger middleware) with reverse proxy in production

@lohithUNE
Copy link

Hey Guys im facing the same issue. Any solution to this. Anything will be greatly appreciated. Thanks.

@lohithUNE
Copy link

@Nepoxx Hey did you find the solution to the swagger on reverse proxy issue. Will be glad if you could help me out. thanks

@vmulex
Copy link

vmulex commented May 25, 2018

Hey Guys,
Add the following item to nginx.conf, may help you!.
proxy_set_header X-Forwarded-Prefix /myservice/;
It works good!.

@DeanB2015
Copy link

@fredtma comment above is the fix to this issue. It worked for me after attempting the other suggestions. This is the solution if you're using angular and ng serve --proxy-config

@mevljas
Copy link

mevljas commented Aug 26, 2021

None of the answers worked for me. I've solved it using a custom middleware.

middlewares/forwardedPrefixSwagger.js

const forwardedPrefixSwagger = async (req, res, next) => {
      req.originalUrl = (req.headers['x-forwarded-prefix'] || '') + req.url;
      next();
};

app.js

app.use('/docs/node/api/swagger/', middlewares.forwardedPrefixSwagger, swaggerUi.serve, swaggerUi.setup(swaggerFile, options));

Note: For this to work the URL must include a trailing slash.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants