session expires not in the expected time in node.js - node.js

I'm pretty new to Node.js and Express-session. I have created a login/registration system, whenever the user logs in redirected to a page called scoreboard.
Problem: Session expires very soon, not the value that I have set it. I don't know how to fix it?
server.js
var session = require('express-session');
app.use(session({
secret: "ILoveMostafa",
resave: false,
saveUninitialized: false,
cookie: {
expires: new Date(Date.now() + 43200)
}
}))
user.js
router.post('/login', (req, res) => {
var email = req.body.email;
var password = req.body.password;
userModel.authenticate(email, password, (err, user) => {
if (err) {
console.log(err)
}
else if (!user) {
console.log('Wrong Password')
}
else {
req.session.userId = user._id;
res.redirect('/user/scoreboard')
}
})
});
router.get('/scoreboard',async (req, res) => {
console.log(req.session.userId)
if (req.session.userId) {
const teams = await userModel.find({}).sort('-score')
const faculties = await userModel.aggregate([{
"$group": {
_id: "$faculty",
average: {
$avg: "$score"
}
}
}]).sort("-average")
res.render('main/scoreboard', {
teamInformation: teams,
finalResult: faculties
})
}
else {
res.redirect('/')
}
});
After about 2 minutes when I refresh the page, I redirected to login page!

Date time is measured in milliseconds.
expires: new Date(Date.now() + 43200) is setting the expire time to be 43.2 seconds later than the present time.

Related

How can i log express-session on socket.io connection?

the problem is when i log req.session.user i get the user results not problem, but when i try to log socket.request.session i get an empty session without the user data, even if i use socket.request.session.user i get user is undefined. whats the problem with it? i really need some help its for my college project which is in the next week
i've followed the docs on socket.io page : https://socket.io/how-to/use-with-express-session
but it doesn't seem like its sharing my session to the socket, im trying to access user data on socket connection
This is my session/socket.io setup
const session = require("express-session");
const sessionMiddleware = session({
secret: "testing",
resave: false,
saveUninitialized: false
});
const wrap = middleware => (socket, next) => middleware(socket.request, {}, next);
module.exports = {sessionMiddleware, wrap};
io.use(wrap(sessionMiddleware));
io.on("connection", (socket) => {
console.log(socket.request.session)
// On new post
socket.on("newPost", (post) => {
console.log(post)
})
console.log(socket.id)
});
and this is my login setup
router.post("/login", async (req, res) => {
const data = {
username: req.body.username.toString(),
password: req.body.password.toString()
}
console.log(data)
if(data.username === "") {
res.json({
status: "error",
message: "Username is required"
})
return;
}
if(data.password === "") {
res.json({
status: "error",
message: "Password is required"
})
return;
}
let user = await new userClass();
if(await user.login(data.username, data.password)) {
req.session.user = await user.getUser();
console.log(req.session.user)
res.redirect("/");
return
} else {
res.redirect("/entry?error=username or password is incorrect");
return;
}
})

Not able to logout using express-session in node.js

I am using express-session in my node.js application for authentication. The login route works fine but I am not able to logout. The session remains there in my mongodb database with a new expiration time when the logout link is clicked.
I have tried req.session.destroy() and req.session.cookie.expires = new Date().getTime() for the cookie to get expired when logout button is clicked but nothing worked.
express-session code in index.js
app.use(expressSession({
secret: 'secret',
cookie: { maxAge: 60 * 60 * 24 * 1000 }, //if maxAge is set to anything between 1000 and 9000 the logout button works
resave: false,
saveUninitialized: false,
store: new mongoStore({
mongooseConnection: mongoose.connection
})
}));
loginUser.js
const bcrypt = require('bcrypt')
const User = require('../database/models/User')
module.exports = (req, res) => {
const {
email,
password
} = req.body;
// try to find the user
User.findOne({
email
}, (error, user) => {
if (user) {
// compare passwords.
bcrypt.compare(password, user.password, (error, same) => {
if (same) {
req.session.userId = user._id
res.redirect('/')
} else {
res.redirect('/auth/login')
}
})
} else {
return res.redirect('/auth/login')
}
})
}
storeUser.js
const User = require('../database/models/User')
module.exports = (req, res) => {
User.create(req.body, (error, user) => {
if (error) {
const registrationErrors = Object.keys(error.errors).map(key => error.errors[key].message)
req.flash('registrationErrors', registrationErrors)
return res.redirect('/auth/register')
}
res.redirect('/')
})
}
auth.js
const User = require('../database/models/User')
module.exports = (req, res, next) => {
User.findById(req.session.userId, (error, user) => {
if (error || !user) {
return res.redirect('/')
}
next()
})
}
logout.js
module.exports = (req, res) => {
req.session.destroy(() => {
res.redirect('/auth/login');
});
I expect the session to get destroyed and the page to be redirected to the login page. Can anyone tell me what i am doing wrong?
try this
module.exports = (req, res) => {
if(req.session) {
req.session.cookie.maxAge = 0
delete req.session
}
res.redirect('/auth/login')
}

req.user clears after 1-2 minutes using passport.js

I am having an issue with my app with the req.user persisting. After a successful login/serializeUser etc, I can see the req.user in the saved, and the application works as desired for about 1-2 minutes. After that, the req.user clears to undefined. I'm using currently using react and calling a method to the server to confirm there is a req.user on componentDidMount. I have no idea why and I'm pretty new to this.
In my server.js:
app.use(bodyParser.json())
// Sessions
app.use(
express-session({
secret: 'feedmeseymour',
cookie: { maxAge: 60000 },
store: new MongoStore({ mongooseConnection: dbConnection }),
resave: false,
saveUninitialized: false
})
)
// MIDDLEWARE
app.use(morgan('dev'))
app.use(
bodyParser.urlencoded({
extended: false
})
)
app.use(bodyParser.json())
app.use(express.static('public'));
app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
// Passport
app.use(passport.initialize())
app.use(passport.session())
My login route:
router.post(
'/',
function (req, res, next) {
console.log('Received login information. Username: ' + req.body.username)
const {errors, isValid } = validateLoginInput(req.body);
if (!isValid) {
return res.status(400).json(errors);
}
next()
},
passport.authenticate('local', {failWithError: true }),
function (req, res, next) {
console.log('req.user in the backend: ' + req.user);
var userInfo = req.user
res.send(userInfo);
},
function (err, req, res, next) {
res.status(401).send({ success: false, message: err })
}
)
passport.serializeUser/deserialize methods:
passport.serializeUser((user, done) => {
console.log('*** serializeUser called, user: ')
console.log(user) // the whole raw user object!
console.log('---------')
done(null, { _id: user._id })
})
// user object attaches to the request as req.user
passport.deserializeUser((id, done) => {
console.log('DeserializeUser called')
User.findOne(
{ _id: id },
'username',
(err, user) => {
console.log('*** Deserialize user, user:')
console.log(user)
console.log('--------------')
done(null, user)
}
)
})
called on componentDidMount:
getUser() {
axios.get('/users').then(response => {
if (response.data.user) {
this.setUser(true, response.data.username, response.data.super);
}
else {
console.log('no user is logged in')
this.setUser(false, null, false);
}
})
}
Which calls this route in the back:
router.get('/', (req, res, next) => {
console.log('req.user:');
console.log(req.user);
console.log('------------');
console.log('req.session:');
console.log(req.session);
console.log('------------');
if (req.user) {
User.findOne({ _id: req.user._id }, (err, user) => {
if (err) {
console.log('logged user retrieval error: ', err)
} else if (user) {
console.log('found user from _id: ' + user);
res.json({ user: req.user, super: user.super })
}
})
} else {
res.json({ user: null })
}
})
req.user exists in the back for about 1-2 minutes and then it goes to undefined. I am storing the user in a store in mongodb, and I can see the session still exists there too.
the req.user is saved with information. In a minute, this will change to undefined:
req.user:
{ _id: 5b7ded93525742053a6dd155, username: 'admin' }
------------
req.session:
Session {
cookie:
{ path: '/',
_expires: 2018-09-09T07:10:22.902Z,
originalMaxAge: 60000,
httpOnly: true },
passport: { user: { _id: '5b7ded93525742053a6dd155' } } }
------------
cookie: { maxAge: 60000 }
That's 60.000 milliseconds, or 60 seconds. Exactly the 1 minute you're describing.
Try storing the user in the session object of the request. This way it works for me.

Save and get the session or cookie with Nodejs and Express not working

I'm pretty new using NodeJs and Express. I'm trying to save a session or a cookie with the user when you log in, and then get it in some other calls. What I'm doing:
server.js: Where I declare the library and create the session.
const session = require('client-sessions');
app.use(session({
cookieName: 'session',
secret: 'JLB_SECRET',
secure: false,
duration: 30 * 60 * 1000,
activeDuration: 5 * 60 * 1000,
}));
login.js: Where the user logs in, here the cookie or session is saved well.
router.post('/login', function(req, res, next) {
console.log('hacemos login', req.session);
var users = req.body;
if (!users.pass || !users.email) {
res.status(400);
return res.json({
status: 400,
error: 'Bad data'
});
}
User.findOne({
email: users.email,
pass: users.pass
}, function(err, userFound) {
if (err || userFound === null) {
res.status(404);
return res.json({
status: 404,
error: 'User not found'
});
} else {
const userToSend = userDto.serviceToDto(userFound);
req.session.user = userToSend; // here is saved properly
console.log('pasamos la session', req.session.user);
return res.json({
user: userToSend,
token: createToken(userFound)
});
}
});
});
Competences.js: I try to get the session in another call, but it's always empty.
router.get('/competence/user/:id', function(req, res, next) {
console.log('veamos la sesion', req.session); //HERE IS ALWAYS EMPTY
Competence.find({
"idUser": mongojs.ObjectId(req.params.id)
}, function(err, competences) {
if (err) {
return res.send(err);
}
const competenceToSend = competenceDto.serviceListToDto(competences);
res.statusCode = 200;
return res.json(competenceToSend);
});
});
Does anybody what I'm doing wrong or how to do it?? Here is where I got the guide to do it: https://stormpath.com/blog/everything-you-ever-wanted-to-know-about-node-dot-js-sessions
Regardssss and thank you!

Delete previous sessions if login from new device MEANJS

I want to remove previous session from MongoStore/sessionStore if a user login from new device. MEANJS is using
express-session
connect-mongo
to store sessions in mongodb. I did search on it but could not find a solution to fetch the list of sessions from db. Please help me here
MongoStore = require('connect-mongo')(session),
favicon = require('serve-favicon'),
module.exports.initSession = function (app, db) {
// Express MongoDB session storage
app.use(session({
saveUninitialized: true,
resave: true,
secret: config.sessionSecret,
cookie: {
maxAge: config.sessionCookie.maxAge,
httpOnly: config.sessionCookie.httpOnly,
secure: config.sessionCookie.secure && config.secure.ssl
},
key: config.sessionKey,
store: new MongoStore({
mongooseConnection: db.connection,
collection: config.sessionCollection
})
}));
};
This should work, at least it's a good starting point for you
var async = require('async'); //npm install async --save
exports.removeSessionsForUser = function(req, res, next) {
var userId = req.user ? req.user.id : undefined;
if (!userId)
return next(new Error('No user found in req. Exiting'));
var store = req.sessionStore;
var sessionsColl = store.db.collection('sessions');
sessionsColl.find({
'session.user': userId,
// we are tryin to remove all sessions, you can leave current
// '_id': { '$ne': req.sessionID }
}, { _id : 1 }, function (err, userSessions) {
async.each(userSessions, function (userSession, cb) {
store.destroy(userSession._id, cb);
}, function(notDone) {
if(notDone)
return next(new Error(notDone));
res.send('ok');
});
});
}
This uses async.each, which is
async.each(Array, function(item, callback) {/* iterate */}, function(error) {/* end */});
Finally with the help I would be able solve the issue
Here is my code
exports.logoutFromPreviousDevices = function (req, res) {
var userId = req.query.userid;
if (!userId)
return res.status(400).send({
message: errorHandler.getErrorMessage('No user found in input request')
});
var store = req.sessionStore;
var sessionsColl = store.db.collection('sessions');
sessionsColl.find({
// 'session.passport.user': userId,
// we are tryin to remove all sessions, you can leave current
// '_id': { '$ne': req.sessionID }
}, function (err, userSessions) {
if (userSessions !== null) {
userSessions.toArray(function (a, sessionsData) {
sessionsData.forEach(function (element, index) {
var data = JSON.parse(element.session);
if (element._id !== req.sessionID && req.query.userid === data.passport.user) {
store.destroy(element._id, function (destroyerr, dat) {
if (destroyerr)
return res.status(400).send({
message: errorHandler.getErrorMessage(destroyerr)
});
res.jsonp({ status: 'Previous session deleted' });
});
}
});
});
} else {
res.jsonp({ status: 'No session found' });
}
});
};

Resources