I have a staging version for my website which is beta.example.com. I recently added cookies authentication with the following setting:
response.cookie(tokenName, token, {
httpOnly: true,
expires: new Date(Date.now() + (tokenExpirationSec * 1000))
})
In staging authentication works.
When I deployed the code to production the cookie was successfully set (via Set-Cookie header) but was not sent to the server in server-side requests. So when I would refresh the logged in state would disappear but would be preserved in client-side requests.
It is worth noting that there's a 301 redirect from example.com to www.example.com. Also the host header was www.example.com in production.
I eventually solved the issue by adding domain parameter when setting the cookie as follows:
response.cookie(tokenName, token, {
httpOnly: true,
expires: new Date(Date.now() + (tokenExpirationSec * 1000)),
domain: '.example.com'
})
However I don't completely understand the source of the problem. According to MDN
Domain specifies allowed hosts to receive the cookie. If unspecified, it defaults to the host of the current document location, excluding subdomains. If Domain is specified, then subdomains are always included.
So when I was in staging with beta.example.com without explicitly setting domain the implicit domain would be example.com according to MDN and beta.example.com would be excluded. But authentication did work in staging!
But I have the same situation in production with www.example.com so why doesn't it work in production?
This is the nginx config which does the redirect:
server {
listen 80 default_server;
server_name beta.example.com;
location / {
include proxy_pass.inc;
}
}
server {
listen 80 default_server;
server_name www.example.com;
location / {
include proxy_pass.inc;
}
}
server {
listen 80;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
I believe you are misinterpreting the MDN documentation.
If unspecified, it defaults to the host of the current document location, excluding subdomains.
Meaning if you are on beta.example.com then Domain will be set to the value beta.example.com. This will exclude the cookie from other subdomains.
You must explicitly set Domain if you would like to use the cookie on all subdomains.