How to access variable inside app.use method in nodejs? - node.js

Here i am trying to access maxAge and expires inside app.use() and inside app.use() method i have session() and inside session() i am assigning maxAge and expires but it's not assiging the value to cookies.
NOTE: i am accessing maxAge and expires from a property file in real application
var maxAge = 3000;
var expires = 3000;
app.use(session({
secret: 'Test API',
name: "test",
saveUninitialized: true,
resave:false,
rolling: true,
cookie: {
maxAge: maxAge, //undifined,
path: '/',
expires: expires //undifined,
overwrite: false,
activeDuration: 24 * 60 * 60 * 1000,
ephemeral: true
}
}));

Related

Express-session not setting cookie in production

I'm using Redis Store to store my sessions since I use a serverless backend, and I'm running into problems to set my cookie.
My frontend and backend currently run on 2 different domains, and this is how I configured my session management:
app.use(json());
app.use(
session({
store: new RedisStore({ client: redisClient }),
secret: options.sessionSecret,
resave: false,
saveUninitialized: false,
cookie: {
secure: process.env.NODE_ENV === 'PROD' ? true : 'auto',
httpOnly: true,
maxAge: 1000 * 60 * 60 * 24 * 7,
sameSite: process.env.NODE_ENV === 'PROD' ? 'none' : 'lax',
},
})
);
As said, the issue occurs when I'm in production, when I'm in development my cookie generates as expected.
Is my session configuration incorrect? Or missing something?
TIA!
As #Brijesh mentioned, we should set a property to trust the proxy:
app.set('trust proxy', 1)
app.use(json());
app.use(
session({
store: new RedisStore({ client: redisClient }),
secret: options.sessionSecret,
resave: false,
saveUninitialized: false,
cookie: {
secure: process.env.NODE_ENV === 'PROD' ? true : 'auto',
httpOnly: true,
maxAge: 1000 * 60 * 60 * 24 * 7,
sameSite: process.env.NODE_ENV === 'PROD' ? 'none' : 'lax',
},
})
);

How to send cookies to client from node/express server?

I am having the hardest time sending cookies from my nodejs server to my browser. Below is my index.js (server side) code:
app.use(express.json());
app.use(express.urlencoded({ extended: true }))
app.use(
cors({
origin: "http://localhost:3000",
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
credentials: true
})
);
let port = process.env.PORT;
if (port == null || port == "") {
port = 5000;
}
mongoose.connect(process.env.ATLAS_URI).then(console.log("MongoDB Connection Success")).catch(err => console.log("MongoDB Connection Failed" + err))
app.use(session({
secret: 'random secret',
resave: false,
saveUninitialized: false,
// store: MongoStore.create({ mongoUrl: process.env.ATLAS_URI }),
cookie: {
expires: 7 * 24 * 6 * 60 * 1000,
secure: false,
},
}));
app.use(cookieParser())
app.use(passport.initialize())
app.use(passport.session())
app.use("/auth", auth)
I know a cookie is being created when i authenticate a user because if i uncomment out the store in app.use(session({...}) i see session IDs and cookies in my mongodb. But how can I send it to the browser?
try this config for the session options.
my version of express-session is "^1.17.2"
app.use(session({
name: 'random name',
resave: false,
saveUninitialized: false,
secret: 'random secret',
store: MongoStore.create({
mongoUrl: config.DatabaseUrl,
ttl: 14 * 24 * 60 * 60 // = 14 days. Default
})
}));
if this config does not work, check your passport authenticate function that set session true like the below example :
passport.authenticate('local.register', {session: true}, (err, user): void => {
// When res has an Error
if (err) return res.redirect('/auth/register');
return res.redirect('/');
})(req, res);

MERN project | Heroku doesn't set client-side cookie

My MERN project work well on my local but when I deployed it I get 401 error while fetching user. Heroku doesn't set client-side cookie. Then I have searched on google first ı change my cookie-session to express-session and some other configuration and still, it doesn't work on Heroku.
https://github.com/olcaykaplan/passport_google
cors:
app.use(
cors({
origin: "http://localhost:3000",
credentials: true,
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
allowedHeaders: ['Content-Type', 'Authorization']
})
);
express session:
app.use(
express.session({
secret: "secret",
resave: false,
saveUninitialized: true,
store: sessionStore,
proxy: true,
cookie: {
httpOnly:true,
secure: true,
maxAge: oneDay,
},
})
);
if your client side work on local,
change secure value to false, remove proxy and sameSite
The project was working fine with the following cors and session information
app.use(
cors({
origin: "netlify url",
credentials: true,
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
allowedHeaders: ['Content-Type', 'Authorization']
})
);
const oneDay = 1000 * 60 * 60 * 24; // Equals 1 day (1 day * 24 hr/1 day * 60 min/1 hr * 60 sec/1 min * 1000 ms / 1 sec)
app.use(cookieParser("secret"));
app.use(
express.session({
secret: "secret",
resave: false,
saveUninitialized: true,
store: sessionStore,
proxy: true,
cookie: {
sameSite:"none",
//path: "/",
httpOnly:true,
secure: true,
maxAge: oneDay,
},
})
);

session is getting expired after closing browser in express.js

I used both cookie-session and express-session, I also specified maxAge but still, it's no use.
const expressSession = require("cookie-session");
const IN_PROD = process.env.NODE_ENV === "production";
app.use(
expressSession({
name: process.env.SESSION_NAME, //setting custom name
resave: false, // do not store if it never modified
secret: process.env.SESSION_SECRETE, // secrete key which we dont't want expose to client
saveUninitialized: false, //dont save the session which is empty
cookie: {
maxAge: 30 * 24 * 60 * 60 * 1000, //Session liftime
sameSite: true,
secure: IN_PROD, //set true when application is in production mode and false when it is in development mode
},
})
);

Session id being same for different client Nodejs

Currently we are setting up session in the cookie using express-session with passport.js and connect-redis to store the data in redis.
I have multiple node server serving requests. For each request without a session, I am creating a new session. Sometimes, an existing session id is being assigned to a new request. Before creating a unique session, I am checking whether the cookie is there...if it is, then I am not creating a new session. But while doing so, we are seeing that same session id being shared with different client.
How do I know its being same?
First user tries to login, it gives successful login and sets up the session and gives the correct information about the user profile.
Second user tries to login, it gives a successful login but sets the session as the previous i.e. first user's session , hence the second user sees the first user info in the profile section.
Code for the Session implementation:
function sessionImplementation() {
return function (req, res, next) {
if(/ucompany=s%3A/.test(req.headers['cookie'])){
var cookie = req.headers['cookie'].split("ucompany=s%3A");
var zCookie = cookie[1].split(".");
var genid = zCookie[0];
return session({
genid:function () {
return genid;
},
store: redis,
cookie: {
maxAge: new Date(Date.now() + (7 * 24 * 60 * 60 * 1000))
},
secret: 'ucomp123',
resave: false,
name: "ucompany",
saveUninitialized: true
})(req, res, next)
}
return session({
store: redis,
cookie: {
maxAge: new Date(Date.now() + (7 * 24 * 60 * 60 * 1000))
},
secret: 'ucomp123',
resave: false,
name: "ucompany",
saveUninitialized: true
})(req, res, next)
}
}
What is the issue and how can I fix it?
Update 1
As per #robertklep I have modified my code.
var express = require('express');
var session = require('express-session');
var RedisStore = require('connect-redis')(session);
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var passport = require('passport');
var app = express();
app.use(bodyParser.json());// to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ extended: false }));
app.use(compress());
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
//app.use(cookieParser());
var redis = new RedisStore({
host:config.redis.url,
port:config.redis.port,
prefix:'sess-'+new Date().getDate()+'-'+(new Date().getMonth()+1)+'-'+new Date().getFullYear()+':'
});
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
store: redis,
cookie: {
expires: new Date(Date.now() + (7 * 24 * 60 * 60 * 1000)),
maxAge:7 * 24 * 60 * 60 * 1000
},
secret: 'ucomp123',
resave: false,
name: "ucomapny",
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
There are several issues with your code:
instead of letting express-session handle the session cookies, you're trying to handle them yourself;
you're instantiating the session middleware for every single request, which is a waste of resources and may also cause problems (I haven't dug into express-session deep enough to make any definitive claims on that);
maxAge (for the cookie) should not be a date but a number (the number of milliseconds from now that the cookie should remain valid); you're confusing it with expires, which is used to set a point-in-time;
The regular way of using it looks like this:
var session = require('express-session');
var express = require('express');
var app = express();
...
app.use(session({
store : redis,
cookie : { maxAge : 7 * 24 * 60 * 60 * 1000 },
secret : 'ucomp123',
name : 'ucompany',
resave : false,
saveUninitialized : true
});
where is a genid ?
you have to generate it yourself. Use uuid package

Resources