How to configure application to be available subdomain cookie? - node.js

I need to share session cookie between main domain and all subdomains. I have two nodejs services based on expressjs framework:
// example.local
...
app.use(session({
cookie: {
domain: "example.local"
}
, key: 'sid'
, secret: '[my secret]'
, saveUninitialized: true
, resave: true
, store: new RedisStore({
host: 'localhost',
port: 6379
})
}));
// blog.example.local
...
app.use(session({
// what should I write here? <---------
}));
So my question is what should I write in session configuration of blog.example.local to get access to existing cookie of example.local?
EDIT: as #yeiniel suggest, I should just use the same config for blog.example.local like the following:
// blog.example.local
...
app.use(session({
cookie: {
domain: "example.local"
}
, key: 'sid'
, secret: '[my secret]'
, saveUninitialized: true
, resave: true
, store: new RedisStore({
host: 'localhost',
port: 6379
})
}));
Is it enough or I may optimize it?

Basically you need two things: Use the same settings on all servers (not just cookie settings but all the session settings included the store) and ensure cookie domain configuration point to the common domain between the sites.

i think your cookie attribute in middleware should be like this,
cookie: {
domain: ".example.local",
path:'/'
}
for blog.example.local and
cookie: {
domain: "example.local",
path:'/'
}
for example.local
Hope this work you.

I am currently managing a similar setup
All apps have the same settings for session
app.use(session({
store: redisStore,
secret: config.secret,
resave: true,
rolling: true,
saveUninitialized: false,
name: config.cookie_name,
cookie: {
domain: config.cookie_domain_name, \\ .website.tld
secure: false
}
You will not be able to use localhost to keep your session data, specially if apps are on different servers. YOu will need a central storage for session data, which all apps can access.

Related

Express doesn't set-cookie when SameSite is none

I have read a lot of other similar questions, but I couldn't solve the issue.
My setup is Node + Express + PassportJs and everything works in development, but I have problems on production.
With the following code, I see that the session cookie is sent back in the response, but I also get a message saying that it won't be applied as SameSite is lax (the default) and the response comes from another site (frontend and backend do not have the same origin).
app.use(
session({
secret: "foo",
resave: false,
saveUninitialized: false,
store: MongoStore.create({ mongoUrl: process.env.MONGO_DB_CONN_STRING! }),
cookie: { httpOnly: true }
})
);
So I changed it to this, so to specify SameSite and Secure in production, but at this point, no cookie is set anymore!
app.use(
session({
secret: "foo",
resave: false,
saveUninitialized: false,
store: MongoStore.create({ mongoUrl: process.env.MONGO_DB_CONN_STRING! }),
cookie: isProduction ? { httpOnly: true, sameSite: "none", secure: true } : {} // <-- only change
})
);
What could be the cause? I've tried to fix it by playing with CORS (no success) and other 100 things. Yet it seems some quirk I am missing.
depending on what service you use to deploy your API(netlify, render.com, heroku other...) you have to enable proxy
this.app.enable('trust proxy');
it fixed my issue

Why can't I set cookies over HTTPS?

I have a server that has its own domain and is using HTTPS. I have a website that has its own domain and is using HTTPS as well.
On the home page of the website, there is a login button and a sign up button. Both buttons lead to forms to execute their respective tasks, and both forms send requests to the server that respond with cookies, or at least that's what they are supposed to do.
I am using express-session in combination with Redis to store the session ids. Here is the config for that (connectToRedis is simply a function that returns a RedisClient):
const RedisStore = connectRedis(session);
const redisClient = await connectToRedis();
app.use(
session({
store: new RedisStore({
client: redisClient,
}),
cookie: {
httpOnly: true,
secure: true,
sameSite: "lax",
maxAge: TEN_YEARS,
},
resave: false,
saveUninitialized: false,
secret: SECRET,
name: AUTH_COOKIE,
})
);
For some reason the cookies are not being sent in the requests. The Set-Cookie header isn't even showing up! I tried changing SameSite to none (article), but that didn't work.
This is my first time deploying a production website, so all this HTTPS stuff is kind of new to me.
Thanks for your help, and if you need any extra information, please let me know.
IMPORTANT UPDATE:
Finally, I have made some progress (all it took was a pizza break).
I added the path key to my cookie config and gave it the value of /. I also set proxy to true.
So now it looks like this:
const RedisStore = connectRedis(session);
const redisClient = await connectToRedis();
app.use(
session({
store: new RedisStore({
client: redisClient,
}),
cookie: {
httpOnly: true,
secure: true,
sameSite: "none",
maxAge: TEN_YEARS,
path: "/",
},
resave: false,
saveUninitialized: false,
secret: SECRET,
name: AUTH_COOKIE,
proxy: true,
})
);
With this, the cookie is finally appearing in the requests, but it isn't being set in the browser...

How to set cookie from express js

I am using express.js as my api faremwork.trying to set browser cookie from expressjs with response.cookie but it is not saving any cookie on my browser.
No Error in console
Already tried httpOnly false/true,secure false/true
res.cookie('nodeSessID', req.sessionID, {maxAge: 24*60*60*1000,httpOnly:false,secure:false,domain:'cz-tuts.com',path:'/'}).json({status:1,message:"success"});
app.use(cookieParser());
app.use('/*',session({
secret: 'ThisisTestSecretForCookie',
// create new redis store.
name: 'nodeSessID',
store: new redisStore({host: 'localhost', port: 6379, client: redisClient,ttl : 260}),
saveUninitialized: false,
resave: true,
cookie: { secure: false,domain:'cz-tuts.com',httpOnly:false,path: '/',maxAge:360000 },
}));
cookie should saved in browser

Nodejs secure cook and HTTPOnly behind proxy server

In Nodejs with secure cookie and HTTPOnly behind a proxy server.
How does HttpOnly flag and Cookie with Secure flag send it headers to proxy server?
I have been reading and assume I need to enable X-Forward-Proto on my proxy server?
process.env.NODE_ENV = 'production';
if (app.get('env') === 'production') {
app.set('trust proxy', 1) // trust first proxy
}
app.use(session({
store: new RedisStore({host: '127.0.0.1', port: 6379, client: client, ttl: 3600}),
key: 'sid',
secret: 'abcde',
resave: false,
saveUninitialized: false,
// proxy: true,
cookie: {
secure: true,
httpOnly: true,
maxAge: 3600000
}
}));
I had a similar problem and solved it with the help of this tutorial.
You also need to set the proxy option to true in your session config.
I would suggest doing this with an environment variable expression process.env.NODE_ENV === "production".
app.use(session({
store: new RedisStore({host: '127.0.0.1', port: 6379, client: client, ttl: 3600}),
key: 'sid',
secret: 'abcde',
resave: false,
saveUninitialized: false,
proxy: process.env.NODE_ENV === "production",
cookie: {
secure: process.env.NODE_ENV === "production",
httpOnly: true,
maxAge: 3600000
}
}));
From the express-session docs:
proxy
Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto" header).
The default value is undefined.
true The "X-Forwarded-Proto" header will be used.
The HttpOnly flag is something that is only considered by a HTTP client. A HTTP proxy will just pass on the flag and ignore it.
As long as the client itself connects to the server (or the proxy, if it's a reverse proxy) with HTTPS, it will work.

connect-mongo cross-domains session issue

I am having a problem with sessions across sub-domains
I use connect mongo like so:
app.use(session({ // req.session is populated
secret: 'xxxxxx',
saveUninitialized: true,
resave: true,
store: new MongoStore({
db: 'nnn'
}),
cookie: {
path: '/',
maxAge: new Date(Date.now() + time),
domain : 'mydomain.com' ,
httpOnly: true
}
}));
However, when I redirect to a subdomain xyz.mydomian.com the session is invalidated. Can anyone recommend a strategy for getting cross domain login to work with connect-mongo ?

Resources