req.session is undefined using express-session - node.js

I am just starting to learn how to use cookies with node and express and I would like some help with getting this to work. I tried to follow the expressjs/session tutorial on GitHub, however I am getting req.session as undefined, so I am unable to set or get any values.
My goal is to save the first and last name of a user to a cookie so that an input field will auto populate. I'm not sure if I need to use cookie-parser as well or if express-session can handle that alone. I'm not sure of how to proceed as I am new to cookies and express-session.
All help is appreciated! Thanks in advance.
Code
let express = require('express');
let app = express();
let credentials = require('../modules/credentials.js');
let session = require('express-session');
let sessionOptions = {
secret: credentials.cookieSecret,
cookie: {
maxAge:269999999999
},
saveUninitialized: true,
resave:true
};
if (app.get('env') === 'production') {
app.set('trust proxy', 1);
sessionOptions.cookie.secure = true;
}
else {
sessionOptions.cookie.secure = false;
}
app.use(session(sessionOptions));
let router = express.Router();
app.use(router);
let request = require('request');
let db = require('../modules/queries');
let bodyParser = require('body-parser');
let cookieParser = require('cookie-parser');
// app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
router.get('/me', function(req, res, next) {
console.log('req.session: '+req.session);
let firstName = req.session.firstName;
let lastName = req.session.lastName;
if (firstName && lastName) {
res.render('student/me.jade', {firstName, lastName});
}
else {
res.render('student/me.jade', { firstName: '', lastName: ''});
}
});
router.post('/api/me', function(req, res, next) {
let firstName = req.body.firstName;
let lastName = req.body.lastName;
// session.firstName = firstName;
// session.lastName = lastName;
req.session.firstName = firstName;
req.session.lastName = lastName;
console.log('session.firstName: '+session.firstName);
db.addEvent(req, res, next);
});
module.exports = router;

Once you mount a router onto an Express app, any subsequently declared middleware on that app won't get called for any requests that target the router.
So if you have this:
app.use(router)
app.use(session(...));
The session middleware won't get called for any requests that get handled by router (even if you declare the routes that the router should handle at some later point). For that, you need to change the order:
app.use(session(...));
app.use(router);
An additional issue is that you're exporting router, which should probably be app (which is the instance that "holds" all the middleware, routers, etc):
module.exports = app;

To get session data
first , You have to initialize express-session with
app.use(session({ resave: true ,secret: '123456' , saveUninitialized: true}));
then When you want to put something in the session
req.session.firstName = 'Aniruddha';
req.session.lastName = 'Chakraborty';
Then you can check without errors
console.log('req.session: '+req.session.firstName);
Note: This is express-sessions work!

This problem occurred with me while trying to maintain req.session object in my app. I was setting req.session.user in a login route, but was not able to get the same outside that route.
console.log(req.session)
// undefined
Since there was no use of cookie in my app, I removed it.
Before removing cookie variable:
app.use(
session({
resave: false,
saveUninitialized: true,
secret: "anyrandomstring",
cookie: { secure: true},
})
);
After removing cookie variable:
app.use(
session({
resave: false,
saveUninitialized: true,
secret: "anyrandomstring",
})
);
This resolved my issue. And now I was able to access req.session from anywhere in the app.
console.log(req.session)
/* Session{
......
......
}
*/
Note: This issue might also occurs if you have initialized app.use(session({...})) at bottom of the file. Try to bring it to the top.
Why this happens: Click here

You will also see req.session === undefined if your Redis connection is invalid or missing!
I don't see anywhere in your code where connection info is being passed when configuring the session.

Another reason why this might happen is if you're making requests from a different URL. Make sure your app is running on the same URL as your Express back-end.

Related

Express-Session Undefined [duplicate]

I am just starting to learn how to use cookies with node and express and I would like some help with getting this to work. I tried to follow the expressjs/session tutorial on GitHub, however I am getting req.session as undefined, so I am unable to set or get any values.
My goal is to save the first and last name of a user to a cookie so that an input field will auto populate. I'm not sure if I need to use cookie-parser as well or if express-session can handle that alone. I'm not sure of how to proceed as I am new to cookies and express-session.
All help is appreciated! Thanks in advance.
Code
let express = require('express');
let app = express();
let credentials = require('../modules/credentials.js');
let session = require('express-session');
let sessionOptions = {
secret: credentials.cookieSecret,
cookie: {
maxAge:269999999999
},
saveUninitialized: true,
resave:true
};
if (app.get('env') === 'production') {
app.set('trust proxy', 1);
sessionOptions.cookie.secure = true;
}
else {
sessionOptions.cookie.secure = false;
}
app.use(session(sessionOptions));
let router = express.Router();
app.use(router);
let request = require('request');
let db = require('../modules/queries');
let bodyParser = require('body-parser');
let cookieParser = require('cookie-parser');
// app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
router.get('/me', function(req, res, next) {
console.log('req.session: '+req.session);
let firstName = req.session.firstName;
let lastName = req.session.lastName;
if (firstName && lastName) {
res.render('student/me.jade', {firstName, lastName});
}
else {
res.render('student/me.jade', { firstName: '', lastName: ''});
}
});
router.post('/api/me', function(req, res, next) {
let firstName = req.body.firstName;
let lastName = req.body.lastName;
// session.firstName = firstName;
// session.lastName = lastName;
req.session.firstName = firstName;
req.session.lastName = lastName;
console.log('session.firstName: '+session.firstName);
db.addEvent(req, res, next);
});
module.exports = router;
Once you mount a router onto an Express app, any subsequently declared middleware on that app won't get called for any requests that target the router.
So if you have this:
app.use(router)
app.use(session(...));
The session middleware won't get called for any requests that get handled by router (even if you declare the routes that the router should handle at some later point). For that, you need to change the order:
app.use(session(...));
app.use(router);
An additional issue is that you're exporting router, which should probably be app (which is the instance that "holds" all the middleware, routers, etc):
module.exports = app;
To get session data
first , You have to initialize express-session with
app.use(session({ resave: true ,secret: '123456' , saveUninitialized: true}));
then When you want to put something in the session
req.session.firstName = 'Aniruddha';
req.session.lastName = 'Chakraborty';
Then you can check without errors
console.log('req.session: '+req.session.firstName);
Note: This is express-sessions work!
This problem occurred with me while trying to maintain req.session object in my app. I was setting req.session.user in a login route, but was not able to get the same outside that route.
console.log(req.session)
// undefined
Since there was no use of cookie in my app, I removed it.
Before removing cookie variable:
app.use(
session({
resave: false,
saveUninitialized: true,
secret: "anyrandomstring",
cookie: { secure: true},
})
);
After removing cookie variable:
app.use(
session({
resave: false,
saveUninitialized: true,
secret: "anyrandomstring",
})
);
This resolved my issue. And now I was able to access req.session from anywhere in the app.
console.log(req.session)
/* Session{
......
......
}
*/
Note: This issue might also occurs if you have initialized app.use(session({...})) at bottom of the file. Try to bring it to the top.
Why this happens: Click here
You will also see req.session === undefined if your Redis connection is invalid or missing!
I don't see anywhere in your code where connection info is being passed when configuring the session.
Another reason why this might happen is if you're making requests from a different URL. Make sure your app is running on the same URL as your Express back-end.

Express session is not keeping its data

I have a mern web app, and I'm using express session. The problem is, the cookie data is not getting saved when I try retrieving it on a different route. It gets set and outputs correctly on the same route, but when I go to another route, and try to retrieve the session data, it returns undefined.
What's weird, is that the session does get stored in mongodb, but I can't retrieve it.
What am I doing wrong and how can I fix it?
Here's the relevant code:
Session.js
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);
const mongoose = require('mongoose');
module.exports = function(app) {
var sess = {
secret: 'mySecret',
cookie: { token: null },
saveUninitialized: false,
resave: true,
store: new MongoStore({ mongooseConnection: mongoose.connection })
};
if (app.get('env') === 'production') {
app.set('trust proxy', 1);
sess.cookie.secure = true;
}
app.use(session(sess));
};
Route.js
module.exports = function(app) {
app.use(cors());
app.use(helmet());
require('../middleware/session')(app);
// Other routes...
};
File1
router.post('/', async (req, res) => {
req.session.token = 'hello';
console.log(req.session.token); // Outputs 'hello'
res.send(req.session.token);
});
File2 This gets called After the page reloads
router.get('/me', async (req, res) => {
console.log(req.session.token); // Outputs undefined
console.log(req.session);
// Outputs: "Session {
// cookie: { path: '/',
// _expires:null,
// originalMaxAge: null,
// httpOnly: true }
// }
res.send(req.session.token);
});
You should add the code below in your app.js file
var cookieParser = require('cookie-parser');
var session = require('express-session');
app.use(cookieParser());
app.use(session({secret: "Funny secret"}));
That's the simple way to do it. Then you may be able to assign and access values to the req.session object.

Setting and Retrieving data from session with express

I am build a small application with node.js and express. In this application there are 2 routes on the backend, one for the users and one for the bugs that users can add.
My goal is to save the user on the session with sessionExpress and then retrieve it when whenever a bug is added to the system.
My code:
app.get('/api/login',(req,res)=>{
const user = req.body
userService.checkLogin(user)
.then(user=>{
req.session.user = user
res.send(user)
}).catch(err=>res.end(err))
})
here I'm saving the user to the session.
app.post('/api/bug/', (req, res) => {
const bug = req.body
console.log(req.session.user)
bugService.add(bug)
.then(bug => res.json(bug))
})
On a different route, I'm trying to get the user back but req.session.user return undefined!
Any help would be much appreciated!
If any more code is needed please let me know
const express = require('express');
const bodyParser = require('body-parser')
const session = require('express-session')
const cookieParser = require('cookie-parser')
var app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))
app.use(express.static("public"));
app.use(session({
secret: 'secret',
resave: false,
saveUninitialized: true,
cookie: { secure: false,maxAge:null }
}))
app.use(cookieParser());
If you are running it from http, can you do trust proxy: 1 and set secure to true. Otherwise cookie-parser will not recognise the cookies.
And from the front-end make sure you are making requests withCredentials.
You are registering the middleware in the wrong order. cookie parser should come before the session since express session uses cookies to save the session.
Note that you application router should come AFTER both of them

firebase express-session dosn't store nothing in the cookies

This is my code:
const functions = require('firebase-functions');
const express = require('express');
const session = require('express-session');
const FirebaseStore = require('connect-session-firebase')(session);
const firebase = require('firebase-admin');
const cookieParser = require('cookie-parser');
const ref = firebase.initializeApp(
functions.config().firebase
);
const app = express();
app.use(cookieParser());
app.set('trust proxy', 1);
app.use(session({
store: new FirebaseStore({
database: ref.database()
}),
secret: 'abigsigrettotheseeiosnofthmbiith765huig',
resave: true,
saveUninitialized: true,
cookie: { maxAge: 60000 }
}));
app.get('/', function(req, res, next) {
console.log(req.session);
req.session.username='xyz';
res.send('Filling the session with data');
});
app.get('/bar', function(req, res, next) {
console.log(req.session);
var sessionData = req.session.username;
res.send(`This will print the attribute I set earlier: ${sessionData}`);
});
exports.app = functions.https.onRequest(app);
When I run this, it creates new session in the DB.
And every time I refresh the page, there is a new session.
I want of course, that only one session would be created,
and that on refresh, this session would only be updated, or to get the data from there. not to create a new one every time.
Checking the cookies - showed me that no cookie is saved / created.
I've been working on this for hours...
this was frustrating when I was using firebase functions and hosting, but can be solved by simply setting name:"__session" in the session.
app.use(session({
store: new FirebaseStore({
database: ref.database()
}),
name:"__session
...

Node-Client-sessions vs express-session

I have this Node API that frontends a backend OAuth server. At the end of the SAML OAuth dance, I set the Bearer Token in a browser cookie.
// need cookieParser middleware before we can do anything with cookies
app.use(express.cookieParser());
// set a cookie
app.use(function (req, res, next) {
// check if client sent cookie
var cookie = req.cookies.cookieName;
if (cookie === undefined)
{
// no: set a new cookie
var randomNumber=Math.random().toString();
randomNumber=randomNumber.substring(2,randomNumber.length);
res.cookie('cookieName',randomNumber, { maxAge: 900000, httpOnly: true });
console.log('cookie created successfully');
}
else
{
// yes, cookie was already present
console.log('cookie exists', cookie);
}
next();
});
app.use(express.static(__dirname + '/public'));
Now I was introduced to a fancy NPM which does pretty much the same thing https://github.com/mozilla/node-client-sessions
While I was almost inclined on using this NPM, I bumped into express-session. https://github.com/expressjs/session - this is for server side sessions. But this also sets a cookie
var express = require('express');
var session = require("express-session");
var app = express();
app.use(session({
resave: true,
saveUninitialized: true,
secret: 'ABC123',
cookie: {
maxAge: 60000
}
}));
app.get("/test", function(req, res) {
req.session.user_agent = req.headers['user-agent'];
res.send("session set");
});
If my need to set only a bearer token in the browser cookie for subsequent API calls, which option should be my choice?
express-session is my go to.
If you look at what it took to accomplish the same thing with the two different methods, I think the answer is clear.
If all you want to do is set a client cookie that will enable the server to correctly authenticate future requests, express-session is awesome.
Here is an example set from another question I answered that uses MongoDB as a backend to store your sessions:
'use strict';
var express = require('express'),
session = require('express-session'),
cookieParser = require('cookie-parser'),
mongoStore = require('connect-mongo')(session),
mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/someDB');
var app = express();
var secret = 'shhh';
app.use(session({
resave: true,
saveUninitialized: true,
secret: secret,
store: new mongoStore({
mongooseConnection: mongoose.connection,
collection: 'sessions' // default
})
}));
// ROUTES, ETC.
var port = 3000;
app.listen(port, function() {
console.log('listening on port ' + port + '.')
});

Resources