nodejs session cookie browser storage - node.js

Server is nodejs with express-session, passport, express
I want to avoid saving a cookie when the user is not authenticated, is this possible?
var sessionStore = new session.MemoryStore;
app.use(session({
cookie: { maxAge: null,
httpOnly: true,
secure: true,
},
store: sessionStore,
resave: 'false',
secret: 'somthing',
name: "id",
saveUninitialized: false
}));
Is it somehow possible to only store the cookie when the user did successfully login? Thanks!

You have to create an express-session: https://www.npmjs.com/package/express-sessions
and then store the session like this:
let session = require("express-session");
app.use(session({
secret: "secret",
resave: false,
saveUninitialized: true,
cookie: {secure: true,
httpOnly: true,
maxAge: 1000 * 60 * 60 * 24
}
}));
This session will be stored during your visit on the webpage. If you want to set values to the cookie, simply request the cookie in a request and set somekind of value:
router.route("/login")
.post(function(req, res) {
req.session.Auth = req.body.user // => user values?
})
OR
You can use cookie-session(https://www.npmjs.com/package/cookie-session)
If you use cookie session then if you made any changes to session variable or from server side, then no need to restart server.
app.use(cookieSession({
name: 'session',
keys: ['key1', 'key2']
}))
app.get('/', function (req, res, next) {
// Update views
req.session.views = (req.session.views || 0) + 1
// Write response
res.end(req.session.views + ' views')
})

Related

Why express session sometimes does and sometimes doesn't make cookies?

I am using cookies like this on my express server :
app.use(
session({
secret: "someStringForSecretKey",
resave: false,
store: new redisstore({ client: RL }),
saveUninitialized: false,
cookie: {
maxAge: 1000 * 60 * 60 * 24,
httpOnly: true,
secure: true,
sameSite: "none",
},
})
);
and sending back the data via axios like this :
axios.defaults.withCredentials = true;
axios.post(`${import.meta.env.VITE_HOSTNAME}/auth`, {
username: userRef.current.value,
password: passwordRef.current.value,
}).then(function (response) .......
I am setting the session as such :
req.session.user = req.body.username;
req.session.save(()=>{
if(req.session.user ){
res.status(200).json({
foo : true
});
}
Now to my surprise the cookie is sometimes set and sometimes isn't. There is no pattern.
Why express session sometimes does and sometimes doesn't make cookies?
httpOnly: true,
Creates undesirable behavior in which it sometimes creates the cookie and sometimes doesn't.
httpOnly: false,
Solved the issue.

Persist expired session data into new session in express js

const adminSession = session({
secret: process.env.ADMIN_SECRET,
resave: false,
saveUninitialized: false,
store: sessionStore,
name: "adminSession",
cookie: {
maxAge: 600000,
secure: false,
},
});
app.use(adminSession());
app.get("/sessionViews", function (req, res, next) {
if (req.session.views) {
req.session.views++;
res.send(`Number of view: ${req.session.vies}`);
} else {
req.session.views = 1;
res.send(" No views");
}
});
Here after the session is expired, req.session.views value is also gone. And new session will be generated with req.session.views=0.
That's how we create the number of views in the certain page, isn't it?
How to keep value persistent with another session?

Express Session lose data before cookie expires

I'm using express-session with redis in my NodeJS Backend.
let redisClient = redis.createClient(6380, process.env.REDISCACHEHOSTNAME, {auth_pass: process.env.REDISCACHEKEY, tls: {servername: process.env.REDISCACHEHOSTNAME}});
app.use(session({
store: new RedisStore({ client: redisClient }),
saveUninitialized: false,
secret: process.env.secret,
resave: true,
cookie: {
maxAge: 1 * 1 * 60 * 60 * 1000
}
}));
On login I store some user details in the session:
req.session.user = result;
And I build a middleware, which log my current session and refresh it on each request:
isOnline = (req, res, next) => {
console.log(req.session);
if (!req.session.user) {
return res.status(401).json({ result: 'Keine Session vorhanden', status: 'failure' });
}
req.session.touch();
next();
};
The extending of my cookie is working well. The cookie expiration datetime is everytime reset to 60 minutes from the request time. Which I can see by the console.log:
Session {
cookie: {
path: '/',
_expires: 2022-03-07T18:46:30.727Z,
originalMaxAge: 120000,
httpOnly: true
},
user: { ... }
}
The issue is, that my user data are lost after 60 minutes. So the cookie itself refreshs, but not the data. So how I can avoid this?

How can I set the domain attribute in express-session based on the request origin?

I'm using express session. I set the domain domain: 'mydomain.com' so that the session cookie can be set between subdomains- like api.mydomain.com and staging.mydomain.com.
But this prevents the Set-Cookie header from setting the cookie when testing with a localhost frontend. I get Set-Cookie was blocked because its Domain attribute was invalid with regards to the current host url.
So I need to make the domain attribute change to localhost if the origin is localhost.
If I conditionally set the domain, we don't have access to req:
app.use(session({
secret: 'very secret 12345',
resave: true,
saveUninitialized: false,
store: new MongoStore({ mongooseConnection: mongoose.connection }),
cookie: {
domain:
req.get('origin').slice(0, 17) === 'http://localhost:' ? 'localhost' : 'mydomain.com',
secure: true,
httpOnly: true,
sameSite: none,
},
})
);
This returns ReferenceError: req is not defined.
So I tried calling session in a custom middleware to get access to req:
app.use((req, res, next) =>
session({
secret: 'very secret 12345',
resave: true,
saveUninitialized: false,
store: new MongoStore({ mongooseConnection: mongoose.connection }),
cookie: {
domain:
req.get('origin').slice(0, 17) === 'http://localhost:' ? 'localhost' : 'mydomain.com',
secure: true,
httpOnly: true,
sameSite: none,
},
})
);
But it doesn't work. It seems that with this, res, req, and next don't get passed in to the middleware function that session() returns. I also trying calling the function session() that returned -session({..options..})() , but that didn't work either.
How can I set the domain attribute based on the request origin?
I had to call the function and pass in req, res, and next
app.use((req, res, next) =>
session({
secret: 'very secret 12345', // to do, make environment variable for production
resave: true,
saveUninitialized: false,
store: new MongoStore({ mongooseConnection: mongoose.connection }),
cookie: {
domain:
req.get('origin').slice(0, 17) === 'http://localhost:' ? 'localhost' : 'mydomain.com',
secure: true,
httpOnly: true,
sameSite: none,
},
},
})(req, res, next)
);

Express Session : terminate session on tab/browser close

I need to terminate the user session or log user out when they close the browser or tab.
Following is the code implemented to maintain session:
app.use(session({
store: new RedisStore({
url: REDIS_CONNECTION_URL,
}),
secret: 'COOKIE_SECRET',
name: 'COOKIE_NAME',
resave: true,
saveUninitialized: false,
rolling: true,
cookie: {
path: '/',
httpOnly: true,
maxAge: 'COOKIE_TIMEOUT',
},
}));
I have tried setting cookie.expires to true but that doesn't help.
You have to handler onclose event of client user, then call a http request to destroy client's session on server side.
Client side:
$(window).unload(function () {
$.get('/session/destroy');
});
Server side:
app.get('/session/destroy', function(req, res) {
req.session.destroy();
res.status(200).send('ok');
});

Resources