I am using express sessions on node.js to store user sessions. I have deployed to an AWS EC2 instance and it works when I call it directly over HTTP. To make the ec2 instance HTTPS, I use AWS CloudFront but then my client cookies are not being set anymore from express session.
I cannot just make the node server directly HTTPS because my SSL certificate is on ACM (which does not allow me to download it).
The express session middleware is shown below. Am I setting this up correctly for HTTPS requests?
let sessionMiddleware = session({
store: new redisStore({
client: redisClient,
ttl: 365*24*60*60
}),
saveUninitialized: false,
resave: false,
secret: "Shh, its a secret!",
cookie: {
httpOnly: false,
secure: true,
expires: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000)
}
});
I fixed the problem by setting the the express session middleware's proxy flag to true. Hope this helps someone.
Related
I have an express session set up to use cookies which get stored in a database. This works perfectly in firefox, but it chrome it doesn't seem to ever save the cookie, so the session is never reflected by the client.
app.use(expressSession({
secret: data[0],
cookie: {
httpOnly: false,
secure: true,
maxAge: 14 * 24 * 60 * 60 * 1000, //14 days
},
store: new connectMongo({mongooseConnection: mongoose.connection}),
resave: false,
saveUninitialized: false,
}));
In firefox, it definitely saves a cookie as connect.sid, and saves data between page loads:
In chrome, it saves some of my browser side set cookies, such as analytics and ones I do with javascript, but connect.sid is never saved.
EDIT: so I've discovered it has to do with secure: true, but I don't want to disable it if I don't have to.
I thought it had to do with xhr.withCredentials but that didn't seem to fix it, plus the page says that it doesn't affect same-site requests, which mine always are.
Not sure where your were hosting your server but after struggling with similar problem you can use the following line, it could be that your server is hosted in places such as heroku as per this other stack overflow thread PassportJS callback switch between http and https
app.set('trust proxy', 1)
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
}));
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've looked at this answer and this answer but no dice. My problem is that when my app is accessed through https://appname.herokuapp.com, everything works fine. but when accessed through https://www.appname.com (which CloudFlare aliases to https://appname.herokuapp.com), it breaks down.
Specifically, when a user logs in, the authentication is processed correctly, but the user session cookie is not set properly. So when the logged-in user is forwarded to the next screen, the request gets rejected as unauthorized.
Right now I am doing this in express:
var mySession = session({
key: "sid",
secret: process.env.SESSIONS_SECRET,
proxy: true,
cookie: {
maxAge: 86400000,
secure: true,
},
store: rDBStore,
resave: false,
saveUninitialized: true,
unset: 'destroy'
});
app.enable('trust proxy');
app.use(mySession);
Am I missing something in my node code, or in my CloudFlare settings?
Could it possibly be related to that CloudFlare puts the node app instanece behind a proxy?
Quoted from expressjs/session documentation:
If you have your node.js behind a proxy and are using secure: true, you need to set "trust proxy" in express.
app.set('trust proxy', 1)
https://github.com/expressjs/session#cookiesecure
I know it is possible to control session start with express and connect middleware. Like suggested here: Controlling Session Start with express and connect middleware
Is it possible to control session start with LocomotiveJS?
I don't want to start session for every user - I just want to start it when user successfully logs in.
I'm already storing session in MongoDb (myabe in the future I will use Redis) and creating not required session for every user which enter the page seems to be a waste of resources.
I just found the solution:
Maybe LcomotiveJS itself does not support it directly, but it can be easily implemented using Express (and Locomotive is on top of it).
Instead of declaring session as:
this.use(express.cookieParser());
this.use(express.session({
secret: '123qwemax',
cookie: {maxAge: 60 * 60 * 1000},
store: new MongoStore({
url: 'mongodb://localhost:27017/tests'
}),
}));
Declare your session as:
this.get(/^\/login\/.*/, express.cookieParser());
this.get(/^\/login\/.*/, express.session({
secret: '123qwemax',
cookie: {maxAge: 60 * 60 * 1000},
store: new MongoStore({
url: 'mongodb://localhost:27017/tests'
}),
}));
This way session will start any time we will go to /login/.* pages.
I don't know why this.all was not working...