I have an express server running which uses vhost to configure subdomain routing. One of the subdomains configured is api. This can be seen in the code snippet below:
// Connect to Mongo database and start express server
connection.once("open", () => {
const server = express()
.use(vhost("api.*", app))
.use(vhost("cdn.*", cdn))
.listen(process.env.PORT || 8080, () => {
console.log("Connected and listening on port " + server.address().port);
});
});
Here, both app and cdn are instances of Express (i.e express apps)
In one of my controllers connected to app, I have the following line of code that uses res.cookie:
res.cookie('state', state.toString(), {maxAge: 3600000, secure, httpOnly: true});
This line used to work before setting up vhost.
Additionally, I have cors configured correctly like this:
app.use(cors({credentials: true, origin: true}));
While testing, I removed vhost (as shown below) and reverted to just using app.listen() and the cookie was being set properly. So this is definitely an issue with the vhost middleware.
const server = app.listen(process.env.PORT || 8080, () => {
console.log("Connected and listening on port " + server.address().port);
})
Edit:
Adding the cookie parser and cors (which are already configured for app) to the main server did not solve the issue:
// Connect to Mongo database and start express server
connection.once("open", () => {
const server = express()
.use(cors({credentials: true, origin: true}))
.use(express.json())
.use(cookieParser())
.use(vhost("api.*", app))
.use(vhost("cdn.*", cdn))
.listen(process.env.PORT || 8080, () => {
console.log("Connected and listening on port " + server.address().port);
});
});
After doing some debugging and testing, turns out since the backend is now on the api.localhost domain and not localhost, the cookie was being blocked by my browser as the sameSite attribute was not set to None and defaulted to Lax.
In a production environment, the cookie would be set correctly assuming the domains match or the sameSite attribute is set to "None" and the secure attribute set to true.