I want to set a top-level domain cookie (i.e. domain:".example.com") from sub.example.com.
I know I have to set the "domain" attribute like so:
const app = express();
app.get("/set", (req, res) => {
res.cookie("name", "express", { domain: '.example.com', path:'/', httpOnly:true, secure:true, sameSite:'lax' }).send("cookie sety");
});
But when I access the page from sub.example.com (Browser, Postman, ...) it always says "domain: .sub.example.com".
The website is running on Windows-Server, IIS 10, Node 20.
IIS is configured for bindings: sub.example.com, example.com (both 80 and 443).
Rewrite-Configuration:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" patternSyntax="ECMAScript" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://localhost:3528/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
I have no idea, at what point the domain get's "rewritten". I checked the web, stack-exchange and copilot. Couldn't find any clue.
I found the solution - I'll try to be as detailed as possible, maybe it helps someone in the future.
Problem in my case: In the reply-header "set cookie", the domain field is - at some point in the reply-flow - rewritten to the actual domain-name including subdomain used to access the site. Independent on what cookie-domain I send in express/nextjs.
The solution: IIS is using ARR 3.0 (Application Request Routing) - which I wasn't really aware off - with a default of "Reverse rewrite host in response header". This is not really visible inside a website configuration because it is configured on IIS-server-level - which I missed looking at.
To change this setting...
Now your headers won't be rewritten for the actual user Domain when calling the site. In my case that's what I want, but keep in mind that you change the behavior of all websites! So double check that you are not creating new errors.