0

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.

xceeded
  • 1
  • 1
  • 3
  • Most probably your nodejs server is not configured with the correct base URL and generates the faulty redirects. – Gerald Schneider Dec 15 '21 at 06:19
  • 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. – xceeded Dec 15 '21 at 06:54

1 Answers1

0

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.
xceeded
  • 1
  • 1
  • 3