Score:0

NGINX reverse proxy doesn't work with swagger-ui-express

in flag

I am using NGINX to proxy_pass all requests with prefix /auth/ to a nodejs api server at localhost:3000.

I have this single config file /etc/nginx/sites-enabled/default3.conf:

server {
    
    location /auth/ {
        rewrite /auth/(.+) /$1 break;
        proxy_pass http://127.0.0.1:3000;
        proxy_redirect off;
        proxy_set_header HOST $host;
    }


}

It works fine for most of my requests (instead of GET http://localhost:3000/logout, GET http://localhost/auth/logout would work as expected), except this request GET http://localhost/auth/docs, which should map to http://localhost:3000/docs but I got a redirect:

HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0 (Ubuntu)
Date: Wed, 15 Dec 2021 01:59:02 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 175
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Security-Policy: default-src 'none'
X-Content-Type-Options: nosniff
Location: /docs/

then a 404 NOT FOUND instead:

HTTP/1.1 404 Not Found
Server: nginx/1.18.0 (Ubuntu)
Date: Wed, 15 Dec 2021 03:20:26 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Content-Encoding: gzip

It seems like when I GET http://localhost/auth/docs, the request hit my nodejs server, but then got redirected back to http://localhost/docs, but how could this be possible? I still can GET http://localhost:3000/docs without a problem.

UPDATED

http://localhost:3000/docs is where I am serving Swagger UI for the server API, using the npm module swagger-ui-express.

in flag
Most probably your nodejs server is not configured with the correct base URL and generates the faulty redirects.
xceeded avatar
in flag
yes you're right. It was a problem with my nodejs app, i.e. the `swagger-ui-express` module. I'm still trying to fix it.
Score:0
in flag

The problem

  • The problem lies in the module swagger-ui-express which my nodejs server is using to serve API docs.
  • I configured it to serve on /docs and the module will make 301 redirects to make the request exactly $HOST/docs, for HOST is whatever the request host is (localhost:3000, or localhost).
  • So, when put behind NGINX reverse proxy like I did, every GET http://localhost/auth/docs would hit my nodejs server but will be redirected to http://localhost/docs like I said in bullet point 2.

The solution

  • Configure NGINX to make another proxy_pass when the request match /docs/.
    location /docs/ {
        proxy_pass http://127.0.0.1:3000/docs/;
    }
  • Be careful that the URI being passed to has a trailing slash, because the module swagger-ui-express expects that trailing slash. Otherwise /auth/docs will be redirected to /docs/ and /docs/ will be redirected to /auth/docs again (infinite loop until error). Although it is okay to remove the trailing slash in both the location matching and the proxy pass URL.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.