nodejs session variable undefined - node.js

I have created a session variable in the login request but unable to access it in logout request(it is undefined).
I want users only that have logged in to request a logout ,if someone who has not logged on requests a logout then ill redirect them to login page.I am using express-session as middleware in the code below.
Here is the session code
var app = express();
app.set('trust proxy', 1); // trust first proxy
app.use(session({
secret: 'nikhilsingh',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}));
Here is the login function
app.post('/login',bodyparserencoder,function(req,res){
console.log('login requested');
let query=require('../'+'dbconnect/'+'login.js');
let exists=query.login({username:req.body.Username,password:req.body.Password},res,req);
console.log('everything done, exists= ' + exists);
req.session.loggedin=true;
});
here is the logout
app.get('/logout',function(req,res){
console.log(req.session.loggedin);
if(req.session.loggedin){
console.log('logout requested');
res.render('Addmie.ejs');}
else{
console.log('login to continue');
}
});
I am new to nodejs ,please ellaborate and explain if I am doing something wrong.Thanks.

I solver this problem by removing the secure attribute from cookie object,anyways I did not understand what actually was causing the problem.

Related

Express-Session: How to keep session alive?

I'm currently using express-session with connect-mongodb-session to store sessions and cookies.
This is my implementation:
app.js
const store = new MongoDBStore({
uri: mongoURI,
collection: 'mySessions'
});
app.use(session({
secret: 'whatever',
store: store,
resave: false,
saveUninitialized: true,
cookie: {
maxAge: 30000 // only 30 secs to to help with testing
}
}))
app.use(express.urlencoded({ extended: true }))
app.use(async (req, res, next) => {
console.log('req.session', req.session)
try {
if (req.session && req.session.userId) {
const user = await User.findById(req.session.userId)
req.user = user
req.session.auth = true
res.locals.auth = req.session.auth
} else {
res.locals.auth = null
}
next()
} catch (error) {
console.log('auth middleware error', error)
}
})
Right now I'm using 30 seconds for maxAge so I can test the behaviour of the app.
What happens is if the user closes the browser and comes back before 30 seconds, they remain logged in. Else, the cookie is no longer valid and the user has to log in again. This is ok.
However, if the user is browsing and, after 30 seconds, they make any request, the cookie is no longer active.
I'd like to make like this:
If the user is using the app, but the 30 seconds maxAge is done, the session and cookie are renewed automatically, with a renewed maxAge, so the user doesn't have to log in again while he is using the app.
But if the user closed the browser and came back after maxAge, they are required to login again (which already happens).
Thank you.

req.isAuthenticated() always returns false outside of passport local strategy

When I call req.isAuthenticated() in my local login strategy upon successful login, it always returns true as it should. However, when I try to call req.isAuthenticated in any other file/route in my express server, it always returns false, even when I have a successful login cookie and session. Does anyone have any idea as to why this is? If not, does anyone have any good open source alternatives to passport.js for auth?
Relevant code from express server:
app.use(session({
secret: process.env.AUTH_SECRET,
resave: false,
saveUninitialized:false,
cookie: {
secure: false,
expires: cookieExpirationDate
}
})); // session secret
app.use(passport.initialize());
app.use(passport.session());
...
app.get('/logincheck', (req, res) =>{ //route called by front end component to check auth status
if(req.isAuthenticated()){ //returns false even with cookie and session in browser
res.json({isAuth: true})
}
else res.json({isAuth: false})
})
Relevant code from local login strategy:
var userinfo = user.get();
req.login(user, function(error) {
if (error) return next(error);
console.log('success!')
})
console.log(req.isAuthenticated()) //always returns true on successful login
return done(null, userinfo);
I've tried all of the relevant solutions discussed in this issue:
passport's req.isAuthenticated always returning false, even when I hardcode done(null, true) so any help is greatly appreciated as I feel like I have been getting nowhere with this problem.

Using a cookie to determine if a user needs to log in again, Node.js and Express

I've a login page (using a HTML form) that when a user enters a password (pre-determined) they can view a site. What I would like is, when the user is logged in, a cookie timer will start and last for 24 hours, when 24 hours expires, they will have to log back in when they view the site. I've done a fair bit of research into this but am struggling a small bit to understand due to my lack of experience with Node.js. I appreciate that using a pre-determined password is poor practice but for what I'm doing, it suits.
Below is the code I have in the server.js file. I had a normal login working prior to starting with cookies so it's just the cookie part I'm having trouble with. Obviously the code below is missing something like MaxAge but I dunno where to implement it.
Thanks
function checkAuth(req, res, next) {
if (!req.session.user_id) {
res.send('You are not authorized to view this page');
} else {
next();
}
}
app.get('/home', checkAuth, function (req, res) {
res.send('if you are viewing this page it means you are logged in');
});
app.post('/login', function (req, res) {
var post = req.body;
if (req.body.name == "login"){
req.session.user_id = "login";
res.redirect('/home');
} else {
res.send('Bad user/pass');
}
});
When you initialise your session, add the maxAge to the cookie.
app.use(session({
secret: 'your secret key',
resave: true,
saveUninitialized: false,
cookie: {
secure: false,
maxAge: 1440000
}
}));
This sets the maxAge of all the cookie. Post which you can check if the request is authenticated.

Session variables in node express-session don't persist to the next request

I am using a basic node express-session setup with memory store and I have this code on the server:
app.use(require('express-session')({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}));
app.post('/api/logIn', function(req, res) {
req.session.userName = req.body.userName;
}
app.get('/api/getProfile', function(req, res) {
User.findOne({'userName' : req.session.userName},
function (err, userProfile) {
console.log('getProfile executed for user:' + req.session.userName);
if (err) throw err;
console.log(userProfile);
});
});
The problem is that req.session.userName from getProfile route is undefined, although it is not in the previous request to logIn route. I inspected HTTP headers and strangely there are no headers dealing with cookies, from the server or from the client. Right now I have no idea what could be the problem.
You say cookie: { secure: true }, but is your web server actually on a secure connection? If not, then the cookie won't be written.
From the docs:
Please note that secure: true is a recommended option. However, it
requires an https-enabled website, i.e., HTTPS is necessary for secure
cookies. If secure is set, and you access your site over HTTP, the
cookie will not be set.
Also its important to note if you are using fetch() to make your API calls to include { credentials: 'include' } in the options of your fetch() call. Otherwise the cookie will not set properly and your session will not persist. Make sure that on your server side you do something like:
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
so that your headers are set properly and cors wont be an issue. Took me awhile to figure this out but its working now!
The session need is stored in a cookie, so we use this to parse it, some like this:
var cookieParser = require('cookie-parser');
// must use cookieParser before expressSession
app.use(cookieParser());
Full example: http://code.runnable.com/U0tEnHwraXYyp-JG/simple-usage-of-express-session-and-cookie-parser-with-express-for-node-js

Node: How do I store data in an express session, so that I can access it from socket.io?

So, for learning purposes, I am writing a chat application with Node and Express. I use MongoDB/Mongoose, Passport for authentification, and socket.io for the actual chat part of the app.
I have a working registration/login/logout system. My problem is in the socket.io code. When I emit a message from a client, I want to know in the sever-side code, from what user the message originated. So, in PHP for example, I would save the user name in a session variable upon login, and later use it from somehwere else. So I attempted to do something similar here:
router.post('/',
passport.authenticate('local',{ failureRedirect: '/login', failureFlash: true }),
function(req, res) {
User.findOneAndUpdate({_id: req.user._id}, { lastConnection: new Date() }, {} ,function (err, user) {
req.flash('welcomeMessage', 'Welcome ' + user.name + '!');
req.session.user=user.name; //Here I try saving the user name
req.session.cookie.user=user.name; //Same here, for testing purposes
res.redirect('/');
});
});
But how do I access this data from within socket.io? In another Stackoverflow question, someone provided the following code for exposing the express session to socket.io:
io.use(function(socket, next) {
var req = socket.handshake;
var res = {};
cookieParser(req, res, function(err) {
if (err) return next(err);
session(req, res, next);
});
});
This permits me to access the session:
io.sockets.on('connection', function (socket) {
//Express session:
console.log("Session: ", socket.handshake.session);
Which gives me this output:
Session: {cookie:
{ path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true
}
}
This does not contain the added data. My guess is, this is the session at the point where my application starts, before I did performed a login, and therefore before any data was added to the session.
Unfortunately, I'm at a loss on how to proceed. I'm grateful for any suggestion :)
In your Session Initialisation change default httpOnly: false settings to true.
Since, it is strict httpOnly it is denying AJAX request.
In your app.js or server.js where you're initialising Session do something like this.
var session = expressSession({
secret: 'secret key',
key: 'express.sid',
resave: false,
saveUninitialized: true,
cookie: {httpOnly: false}
});
Note: cookie: { httpOnly: false } is important, rest code is for example.
Thanks.

Resources