Score:0

Allow CORS Headers pass through in apache2 reverse proxy setup

in flag

I came down to ask here since I am troubleshooting this for days without any success. What I try to accomplish is to set up a reverse proxy to the nodejs/Express backend using apache2. Proxying the http and websocket connections work fine, however, enabling CORS does not work. I need it as the Application provides a widget that will be imported by the client on the external host. The curcial information here is that cors should be handled by the cors() middleware by expressjs, and all related headers / requests should simply be proxied forth and back to this backend server via apache2. Here is my current configuration with some comments on how I understand the different directives:

<VirtualHost my.domain.name:80>
 # redirecting all requests to https (works fine)
</VirtualHost>

<VirtualHost my.domain.name>
 
 LogLevel debug # does not log any information regarding the headers

 ServerName my.domain.name
 ServerAdmin [email protected]

 ## SSL directives removed for clarity
 ## logfile directives removed for clarity

 # forward requests to proxy =>
 ProxyPreserveHost On # Not sure if this is required as I forward the Origin header

 <Location "/"> # proxy all requests
  RequestHeader set Origin %{HTTP:Origin}e
  ProxyPass "http://localhost:3333/" # location of the backend server
  ProxyPassReverse "http://localhost:3333/" # required
 </Location>

 #ProxyRequest Off # Throws an error (unknown directive), but disabled by default, so not required
 
 # forward socket.io requests removed for calrity

 ## Required headers for CORS:
 # crucial CORS-related header that indicates the origin of the requesting domain
 RequestHeader set Origin "%{ORIGIN}e"

 # used in CORS preflight requests to indicate the HTTP method
 RequestHeader set Access-Control-Request-Method "%{REQUEST_METHOD}e"

 # used in CORS preflight requests to indicate the requested headers
 RequestHeader set Access-Control-Request-Headers "%{HTTP_ACCESS_CONTROL_REQUEST_HEADERS}e"

</VirtualHost>

Locally I used nginx to test the widget behind a reverse Proxy and it is working fine (including CORS from another port):

server {
   # omitted meta and SSL specific directives for clarity
 
   location / {
    proxy_pass      http://127.0.0.1:3333;

    # enable websocket passthrough
    proxy_http_version  1.1;
    proxy_set_header    Upgrade $http_upgrade;
    proxy_set_header    Connection "upgrade";

        proxy_set_header        Host $host;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto $scheme;
   }

}

I see that nginx is not setting the origin or anything related to the OPTIONS preflight request. Also, Host and X-Real-IP are not directly related to cors, as far as I can tell. I wonder why this was working. Note that I included the X-Forwarded-* headers in the apache2 config before (to no avail) to ensure that the cors middleware in express does not complain about missing information when it discovers a proxied request. My brain is melting from reading the apache2 docs regarding mod_proxy and mod_headers as well as searching the web for information about how to do this, and I really hope you can enlighten me what I am missing / doing wrong here. Thank you in advance !

Edit To be more specific about my question: How can I debug what headers apache modifies, if any? I started to dig into the cors middleware and print out headers on the Express Server side, but for now, I am not much smarter. I will have more time at the weekend I hope, and will further update this question.

Edit2 I added a middleware to the expressjs backend to log the request headers:

app.use((req, res, next) => {
    console.log("Request Headers:", req.headers);
    next();
});

And it turns out that the "origin" header, although set by the original request, indeed was not correctly passed to the backend:

Request Headers: {

// ...
   origin: '(null)',

// ...
}

It took me a while to figure out how to access the Origin header value and pass it to the backend, but I found a solution for the origin (I got goosebumps like crazy when I did, ha(!)). I will post my solution as an answer for future reference. (Spoiler: Neither the HTTP:Origin nor the Origin or ORIGIN environment variables were set..).

I sit in a Tesla and translated this thread with Ai:

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.