1

Hi I'm running Laravel on NGINX server and I would like to use NGINX reverse proxy capability as an API gateway for my Laravel and other node API application. Here are my configurations:

Application URL: staging-app.example.com
Application API Endpoint: staging-app.example.com/api
API Gateway URL: api.example.com

What I want to do, is to redirect all API requests api.example.com/staging-app to staging-app.example.com/api. I have succeed in redirecting the API request, but somehow the Authorization header is not passed along to the proxy pass resulting in 401 unauthorized while other header do get passed along.

Here is my current api.example.com nginx config:

server {
        server_name api.example.com;


        location /staging-app {
                rewrite ^/staging-app/(.*)$ /$1 break; 
                proxy_pass http://staging-app.example.com/;
        }

        location /test {
                rewrite ^/test/(.*)$ /$1 break;
                proxy_pass http://127.0.0.1:3333/;
         }

    listen [::]:443 ssl; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = api.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen 80;
        listen [::]:80;

        server_name api.example.com;
    return 404; # managed by Certbot
}

and for my laravel application, I use the configuration given from Laravel themselves

Update 1: I tried adding proxy_set_header Test testingvalue in the location block directly, but it doesn't seems to work either

  • Nothing should prevent nginx to pass the `Authorization` header to your upstream. However you are not passing your request to the `/api` endpoint; to do it, use `location /staging-app { proxy_pass http://staging-app.example.com/api; }` instead. Actually, no rewrite rules are required for your configuration to strip the URI prefix at all; check [this](https://stackoverflow.com/questions/53649885/a-little-confused-about-trailing-slash-behavior-in-nginx) SO thread to find out why. – Ivan Shatsky Jun 02 '22 at 13:54
  • I have installed [telescope](https://laravel.com/docs/9.x/telescope) which allows me to see incoming requests. The request arrive successfully with the correct endpoint, but it's missing `Authorization header`. When I try adding another header such as `authorizationzz` it get passed through. – Kevin Yobeth Jun 05 '22 at 03:19
  • To check what exactly appears at the backend, I'm using a debug script with the content like [following one](https://gist.github.com/ivanshatsky/7980be97979fb2bdd8ef3b605543827e); it shows the `Authorization` header is passing correctly, so I think it is a Laravel who is in charge of it's disappearing. – Ivan Shatsky Jun 07 '22 at 19:20
  • @IvanShatsky I have tried running a node.js server and assign it a subdomain, when I proxy_pass to the IP (127.0.0.1:3333) the header went through, but when I use the subdomain, it disappear. – Kevin Yobeth Jun 09 '22 at 02:33
  • An `Authorization` header can be lost if you are 1) requesting auth and passing the `Authorization` header using different protocols (HTTP/HTTPS); 2) receiving a redirect (see related [so] threads: [1](https://stackoverflow.com/questions/28564961/authorization-header-is-lost-on-redirect), [2](https://stackoverflow.com/questions/18914076/can-a-http-redirect-instruct-the-client-to-strip-a-specific-header-from-the-requ)); 3) dealing with the CORS `OPTIONS` request (see related [so] [thread](https://stackoverflow.com/questions/72279922/authorization-header-in-nginx-subrequest-is-missed)). – Ivan Shatsky Jun 09 '22 at 13:21
  • What you have in your config right now is not a redirection but a reverse proxying. As already being said, I don't understand how your `/staging-app` request can be passed as `/api` (however the `/staging-app/api` request will be passed as an `/api`). Did you check your actual `api.example.com` with `curl`? Can't it be a some kind of redirection? – Ivan Shatsky Jun 09 '22 at 13:25

2 Answers2

0

Try adding the following to your config for the server listetning on port 443 :

proxy_http_version 1.1;
proxy_set_header   "Connection" "";

This will make the conection from master and agents presistent which is needed for authenticaiont in some setups

config doc

nginx keep-alive doc

ofirule
  • 143
  • 7
  • Nope the Authorization header still won't get through. I tried adding the `proxy_set_header Test testingvalue` in the location block directly, but somehow the value isn't added to the request. – Kevin Yobeth Jun 05 '22 at 03:24
  • Not passing headers is really weird. It probably requiire further investigation. Try adding the first four configs from link: https://www.nginx.com/resources/wiki/start/topics/examples/full/#proxy-conf – ofirule Jun 06 '22 at 08:46
  • Still doesn't work @ofirule – Kevin Yobeth Jun 09 '22 at 02:40
  • It probably requiire further investigation. I would recomand using `tcpdump` and/or `wireshark` for investigating the traffic – ofirule Jun 09 '22 at 08:41
0

Have you tried this answer?

Add to location block this entries

proxy_set_header  Authorization $http_authorization;
proxy_pass_header Authorization;
Alexander Tolkachev
  • 4,513
  • 3
  • 14
  • 23
  • Nope still didn't work, I even manually set $http_authorization with hardcoded token. Still didn't went through. I have tried running a node.js server and assign it a subdomain, when I proxy_pass to the IP (127.0.0.1:3333) the header went through, but when I use the subdomain, it disappear. – Kevin Yobeth Jun 09 '22 at 02:38