I am writing two application on localhost and don't want them to share certain information (Likely on session).
I am wondering if I can open two port? Is the Session storage port specific?
I am wondering if I can open two port?
Yes, you listen on two ports, by starting two servers, one for each port.
Is the Session storage port specific?
Yes and no. It depends upon how the session is configured.
Cookies are not port-specific so by itself a session cookie would be shared between two servers on the same host, but different ports.
So, if you want two instances of express-session on two separate web servers on the same host, but separate ports to use separate sessions, then you can initialize express-session to use separate cookies for each session (by specifying a different cookie name for each) and initialize two separate instances of express-session and then the two sessions will be completely separate.
Here's an example:
const express = require('express');
const session = require('express-session');
// configure first server and session middleware
const app1 = express();
app1.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: true },
name: 'session1'
}));
app1.listen(8080);
// configure second server and separate session middleware/session cookie
const app2 = express();
app2.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: true },
name: 'session2'
}));
app2.listen(8081);
And, if you're specifying a specific storage medium for the session, then you need to make sure you initialize those to be separate storage locations.
Related
Currently, I have a node application where I need to check the specific session store I am using to manage store session variables. I never explicitly configured this (though someone else working on the same codebase could have) and haven't been able to find anything specific, and I need to know if the session store uses the touch method to know if I should set the resave proprty of sessions to true or false.
First of all, you need to locate the express-session usage in your code base.
Should be in your server.js or app.js file. Being used as
app.use(session({...properties}));
For example it may look like this:
app.use(session({
saveUninitialized: true,
resave: true,
secret: 'secret-123',
cookie: { secure: false, httpOnly: true, maxAge: 60000 },
store: new CouchbaseStore({
db: connectionObj,
prefix: 'test'
})
}));
the default store is the Memory of the server. So you can override the store with connect-mongo, connect-couchbase, connect-redis and what not.
After we migrated our website from http scheme to https (including enabling https on CDN and redirecting http to https on server), we found that our user sessions works incorrectly sometimes, that is, the user A would be recognized as user B! It seems the session ids of cookies are incorrectly parsed and maybe different users share the same cookies or session ids but all the session ids are generated by uid-safe uniquely.
The issue seems very strange and we really have no idea of the cause.
we use nodejs, Express, express-session with redis storage.
The express-session setup is as below:
app.use(session({
secret: 'xxxx',
cookie: {
maxAge: 3600*24*90*1000
},
store: new redisStore(),
resave: false,
rolling: true,
saveUninitialized: false
}));
Every time I close all the browser windows and then open the web app again, a new session is established, that means I have to authenticate again.
For your reference, I use express#4.14.0 as the web application framework, express-session#1.14.1 + connect-mongo#1.3.2 as middleware to store the sessions and passport#0.3.2 for authentication.
Below is the code for cookie and session configuration:
// CookieParser should be above session
app.use(cookieParser());
// Express MongoDB session storage
app.use(session({
resave: true,
saveUninitialized: true,
name: config.sessionName,
secret: config.sessionSecret,
store: new MongoStore({
mongooseConnection: db.connection,
collection: config.sessionCollection
})
}));
The "old" session stored in MongoDB still has two weeks to expire.
It seems like the Node.js application cannot recognize the "old" session from browser, therefore create a "new" one and tell the browser to use the "new" one.
It does not happen occasionally, but always, so I believe there is something wrong in my web application.
Thanks to #Bradley, finally I figured out what's wrong.
This is my solution
app.use(session({
cookie: {
maxAge: ms('14 days') // `ms` is a node module to convert string into milliseconds
},
resave: true,
saveUninitialized: true,
name: config.sessionName,
secret: config.sessionSecret,
store: new MongoStore({
mongooseConnection: db.connection,
collection: config.sessionCollection
})
}));
For more information, please refer to https://github.com/expressjs/session#expires
By default, no expiration is set, and most clients will consider this a "non-persistent cookie" and will delete it on a condition like exiting a web browser application.
That's why I encountered this problem.
I'm busy building a platform with 3 different subdomains - example.com, auth.example.com and api.example.com. They're run with 3 separate NodeJS apps running on different ports of the server.
Here is the code setting up the sessions:
var session = require("express-session");
var redisStore = require("connect-redis")(session);
var redisClient = require("redis").createClient(config.redis);
app.use(session({
secret: config.server.secret,
store: new redisStore(config.redis),
client: redisClient,
resave: false,
saveUninitialized: false,
cookie: {
domain: "example.co.za",
httpOnly: false
}
}));
The configuration is exactly the same for all 3 apps and they're sitting on the same server. For some reason, the sessions are not being shared. I seem to remember that they were being shared a few weeks back and now things are broken - I have a sneaky suspision that this happened when we moved all the traffic from HTTP to HTTPS. Would this break the sessions? I tried to turn of 'httpOnly' in case it restricted the sessions, but no luck.
I have run redid-cli MONITOR and the session is, in fact, being saved on login (Auth App) but is not being retrieved by the other app. When I turned saveUninitialized to true, the requests to save were coming from all 3 apps - this shows that they are connected to the same Redis Store.
Any help would be great.
I think this is just a cookie issue. The browser is not sending the session cookie back on your sub-domains:
you need a leading . on the domain. e.g.:
cookie: {
domain: ".example.co.za",
httpOnly: false
}
In case that doesn't work and you are having AJAX issues see this post
I have a Node/Express application that use redis as session store.
I have a question concerning the handling of the expiry of the session.
I'd like have an active session until the browser is closed, so I didn't set a session expiration time.
Doing that the session cookie works fine, but I have a doubt about Redis.
It seems that the couple Key/Value stored in Redis DB never expire.
How is the right way to handle this?
There is a way to configure redis to destroy a value stored with a certain idle time?
Or is better set a TTL when the connect-redis is invoked inside the application?
Actual configuration of the session inside the application:
var session = require('express-session');
var RedisStore = require('connect-redis')(session);
app.use(session({
store: new RedisStore({port:6379, host: 'localhost'}),
secret: "my-secret-here",
resave: false,
saveUninitialized: true }));
Using Redis with express-session, you can use the touch() method from express-session to reset the TTL. So if you set a TTL when creating the session, do something like this on the routes where you don't want the session to expire:
api.get("/someRoute/", (req, res) => {
req.session.touch();
// Whatever else you need to do
res.sendStatus(200);
}
That will reset the TTL on Redis and prevent the session from expiring assuming the client is still hitting your API - I'm assuming that if the client doesn't interact with your API for long enough, that implies the browser is closed or otherwise finished using your app.
You can specify a ttl while creating the session store.
You can find more options in the readme.
app.use(session({
store: new RedisStore(options),
secret: 'keyboard cat',
ttl : 20 // ttl is in seconds. From the readme.
}));