DEV Community

Discussion on: Hosting a Node.js application on Windows with IIS as reverse proxy

Collapse
 
jmanuel_velasco profile image
JManuel • Edited

Hello, this is a great solution and help me to deploy the API following IT restrictions I have. Thanks for sharing it!. However, I found a problem I don't know if it is posible to solve, if it is, I need help to figure out how.

I have a non-node API published under a domain (api.example.com) listening on 443 (on IIS, that is why I am here :/)
We need to publish a node API and since IT doesn't allow to open different ports than 80 and 443, I have found the reverse proxy a great solution. I have achieved to set up everything and serve the API correctly. In the root folder where api.example.com is I added the following rewrite rule

            <rule name="ReverseProxyInboundRule1" stopProcessing="true">
                <match url="^my-node-api/(.*)" />
                <action type="Rewrite" url="http://localhost:3000/{R:1}" />
            </rule> 
Enter fullscreen mode Exit fullscreen mode

And I am able to request:
api.example.com/my-node-api/
endpoints perfectly.

Now the problem:
In the web.config where I set up the rewrite rule, I need to have customHeaders section to define CORS, besides the rewrite section I also have the following section in the web.config file:

    <httpProtocol>
        <customHeaders>
            <add name="Access-Control-Allow-Origin" value="https://www.example.com" />
            <add name="Access-Control-Allow-Methods" value="PUT,GET,POST,HEAD,DELETE" />
            <add name="Access-Control-Allow-Headers" value="Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With" />
            <add name="Access-Control-Allow-Credentials" value="true" />
        </customHeaders>
    </httpProtocol>
Enter fullscreen mode Exit fullscreen mode

The problem is the node-api can't manage the "Allow-Origin" by its own because it is taking the web.config definition from its main domain "api.example.com" too, so at the end there are two different allow origin values and it is blocked by CORS when trying to consume my-node-api from another domain than example.com.

I can't use * because I need Allow-Credentials set to true, and * is not valid in this case.

I think if the httpProtocol customHeaders settings could be not inherit from child applications (I mean following the description I shared, "my-node-api" application) it will work, since I will be able to manage the allowed origin in the node-api without getting the customHeaders defined in the parent application (api.example.com)

Is that possible ?
how can I do it if this is the case?

I will appreciate any hint/advice, even a confirmation what I am trying to achieve is not posible, having this reverse-proxy solution working restricted to a site only.

Thanks for your time!
·_-

Collapse
 
petereysermans profile image
Peter Eysermans

Is there a reason why your node api is in a subfolder of your non-node api? The node api can perfectly reside in a different folder and be run from there. Next to that, the folder where the IIS website for the reverse proxy is pointing to does not have to be the node api folder. You can put the web.config in a separate folder and point the reverse proxy website to that folder. Hope this helps you further.

Collapse
 
jmanuel_velasco profile image
JManuel

Hello,

oops, I am late... I didn't realised I had a comment

Yes. We have only certain domains allowed to use due to WAF protection and only 80 and 443 ports are enabled, so I only have one IIS Site binding to publish different APIs.

api-domain.example.com

What I have done is to publish the initial API binding to the domain in a separate internal IIS site, and from the api-domain.example.com site definition I have another reverse proxy rule for it.

<rule name="Backend API ReverseProxyInboundRule" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://my-backend-api.example.com/{R:1}" />
</rule>
Enter fullscreen mode Exit fullscreen mode

together with the ones for my node APIs

<rule name="NodeAPI ReverseProxyInboundRule1" stopProcessing="true">
<match url="node-api-1/(.*)" />
<action type="Rewrite" url="http://localhost:3000/{R:1}" />
</rule>
Enter fullscreen mode Exit fullscreen mode
<rule name="NodeAPI ReverseProxyInboundRule2" stopProcessing="true">
<match url="node-api-2/(.*)" />
<action type="Rewrite" url="http://localhost:8000/{R:1}" />
</rule>
Enter fullscreen mode Exit fullscreen mode

Like so I can apply the site httpprotocol definitions only to my-backend-api.example.com site binding definition, and let node to manage the CORS from the application.

At least this has been my final undertanding and how I have deployed,
If something is not correct, happy to know.

If this helps someone, glad to know.

Cheers,
·_-