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
Related
After the latest updates in chrome, the browser is not saving my server cookies. Previously, it was working even it showed a warning about it. But now it is not.
Since my react app is hosted on netlify and my server runs on AWS, it is cross-origin. So, I have changed my cookie settings in express-session with sameSite=None secure options as follows.
app.use(session({
secret: 'my secret',
name: 'my-react-app',
resave: false,
saveUninitialized: true,
cookie: {
secure: true,
sameSite: 'none',
maxAge: 24 * 60 * 60 * 1000,
httpOnly: true
}
}));
After setting secure: true, it does not even work in firefox. The website is served over https. I've tried almost all combinations with these params. Am I missing anything? Any help would be appreciated.
I found the solution finally.
Actually, it has nothing much to do with express-session settings, in which I spent a lot of hours. The main reason behind this is misconfigured reverse proxy. In my case, connection between the reverse proxy and application server was not https. Because of that, the secure flag in the cookie is not applied, which in turn results into setting sameSite option to default 'lax' value. And, that's why my cookies got rejected in a cross-origin request.
To solve this, I have to set X-Forwarded-Proto in the proxy header.
Open reverse proxy configuration file
sudo nano /etc/nginx/conf.d/sysmon.conf
in my case, and add the following line.
proxy_set_header X-Forwarded-Proto $scheme;
This will forward request over https.
And you also need to set "trust proxy" in express.
var app = express()
app.set('trust proxy', 1) // trust first proxy
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.
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