req.session is undefined nodeJS - node.js

im trying to set up a session in NodeJS and use it in my /auth route after that but i'm getting undefined troubles with the session.
In the app.js :
const express = require('express'),
path = require('path'),
bodyParser = require('body-parser'),
cors = require('cors'),
mongoose = require('mongoose'),
config = require('./config/DB');
const app = express();
const session = require('express-session')
const MongoStore = require('connect-mongo')(session);
mongoose.connect(config.DB, { useNewUrlParser: true }).then(
() => { console.log('Database is connected') },
err => { console.log('Can not connect to the database' + err) },
options
);
const db = mongoose.connection
const adUnitRoutes = require('./routes/adunit.route');
const userProfileRoutes = require('./routes/userprofile.route');
app.use('/adunits', adUnitRoutes);
app.use('/userprofile', userProfileRoutes);
app.use(session({
secret: 'my-secret',
resave: false,
saveUninitialized: true,
store: new MongoStore({ mongooseConnection: db })
}));
In the route :
userProfileRoutes.route('/authentification').post((req, res) => {
console.log('req session : ' + req.session.userId);
//here I got cant read property of userId because session is undefined
});

This happens because you are setting your routes before adding the middleware. Your handlers are essentially middleware so if they are added before session, your session has not been processed and added to the request yet.
Adding the routes after setting your middleware will make it work as expected.
See this minimized example:
const express = require('express');
const app = express();
const session = require('express-session');
app.get('/broken', (req, res) => {
console.log('req session : ' + req.session.userId);
res.write(String(req.session.userId));
req.session.userId = 1;
res.end();
});
app.use(
session({
secret: 'my-secret',
resave: false,
saveUninitialized: true
})
);
app.get('/ok', (req, res) => {
console.log('req session : ' + req.session.userId);
res.write(String(req.session.userId));
req.session.userId = 1;
res.end();
});
app.listen(8089);

Related

how to pass the already running db connection into the mongo store for storing sessions

I am new to backend development so I am facing some problems.
I have used mongoose.connection() to connect my db into the server.
Now I want to store the user sessions into the database and for that I have used express-session andmongo-store for that. To create mongo-store instance, I have to again pass the database string and its other options to run a new db connection. Can I overcome this somehow ?
const express = require('express');
const mongoose = require('mongoose');
const session = require('express-session');
const passport = require('passport');
const cookieParser = require('cookie-parser');
const MongoStore = require('connect-mongo');
require('dotenv').config();
const app = express();
//Passport config
require('./config/passport');
// //Connect To DB
const dbOptions = {
useNewUrlParser: true,
useUnifiedTopology: true
}
//--------------Here I have created a connection with the database----------------------//
mongoose.connect(process.env.DB_String, dbOptions)
.then(() => { console.log("Connected to the databse....") })
.catch(error => console.log('Error While Connecting to db', error));
//Middleware to read the body of requests
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
//Express session middleware
app.use(session({
secret: process.env.Session_Secret,
resave: true,
//---------Here I am creating a new connection with the database for storing sessions--------//
store: MongoStore.create({
mongoUrl: process.env.DB_String,
mongoOptions: dbOptions,
collection: 'sessions'
}),
saveUninitialized: true,
cookie: {
maxAge: 1000 * 60 * 60 * 24
}
}));
//Passport middlewares
app.use(passport.initialize());
app.use(passport.session());
//Endpoints
app.use('/api/', require('./api/index'));
app.use('*', (req, res) => {
res.status(404).json({message: 'Route not found'});
})
//Listen to the port
app.listen(process.env.port, () => {
console.log(`app is listening on port ${process.env.port}`);
});
You should do:
store: Mongostore.create({
mongooseConnection: mongoose.connection
})
And if this doesnt work declare your mongostore like this:
const MongoStore = require('connect-mongo')(session);

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.

exporting/using express-session in another file

What's the best/common way to use an express-session in other files? I have trouble integrating the session into my code. I was using auth tokens, but I would like to use sessions instead.
I defined session in my server.js:
const express = require('express');
var session = require('express-session');
var cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser('secret'));
app.use(session({
key: 'user_sid',
secret: 'secret',
resave: false,
saveUninitialized: false,
cookie: {
expires: 600000
}
}));
// stuff
module.exports = {app, session};
And it works fine! But When I try to use it in my userController.js:
var express = require('express');
var {session} = require('./../server');
module.exports.login = (req, res) => {
var body = _.pick(req.body, ['email', 'password']);
User.findByEmailAndPassword(body.email, body.password).then((user) => {
// console.log(req.session); // is undefined
res.render('dashboard.hbs');
}).catch((e) => {
res.status(400).send();
});
}
then req.session is undefined.
I know what I'm doing isn't right, obviously, but what's the right way to do it?
Thanks!
I think you don't have to export session at all, as you are telling your app to use it in server.js.
So the working fiddle should be looking like the following:
const express = require('express');
var session = require('express-session');
var cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser('secret'));
app.use(session({
key: 'user_sid',
secret: 'secret',
resave: false,
saveUninitialized: false,
cookie: {
expires: 600000
}
}));
// stuff
module.exports = app;
and your controller:
module.exports.login = (req, res) => {
var body = _.pick(req.body, ['email', 'password']);
User.findByEmailAndPassword(body.email, body.password).then((user) => {
// console.log(req.session); // is undefined
res.render('dashboard.hbs');
}).catch((e) => {
res.status(400).send();
});
}
I am considering that you are going to use this exported login function for a route, like
app.use('/login', require('yourCtrl.js').login);

How to make userid in nodejs express session persist after login event?

Session userid not available as session gets refreshed in express nodejs . Even though it reappears after webpage is refreshed. I am using express session.
I am accessing my nodejs socket app through an external url like this-
socket = io.connect('https://xxx.xxx.net:3000/')
var uid = app.user.get('id');
socket.emit("login_register", { user: uid });
Server file code-
var crypto = require('crypto')
const http = require('https')
const express = require('express')
const cookieParser = require('cookie-parser')
const mysql = require('mysql')
const socket = require('./socket')
const routes = require('./routes')
var bodyParser = require('body-parser');
const { sessionMiddleware } = require('./middlewares')
var app = express();
const server = http.createServer(options,app)
const io = socket(server)
io.use((socket, next) => {
sessionMiddleware(
socket.request,
socket.request.res,
next
)
})
app.use(sessionMiddleware)
app.use(express.static('public'))
app.use('/', routes)
app.use(cookieParser())
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With,
Content-Type, Accept");
next();
});
io.on('connection', socket => {
console.log('in on');
const req = socket.request
socket.on("login_register", function (data) {
x = JSON.stringify(data);
console.log('login-- '+x);
const { user } = data
req.pass = user
req.session.userID = user
console.log('loginuser-' + req.session.userID)
console.log('sessionTD-'+socket.request.sessionID);
console.log(socket.request.session);
req.session.save();
});
console log data -
in on
sessionTD-gp0cmPbWlWrwVuMlb3wlFwEJayhNRy7D
undefined
login-- {"user":"121"}
loginuser-121
sessionTD-gp0cmPbWlWrwVuMlb3wlFwEJayhNRy7D
Session {
cookie:
{ path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true },
userID: '121' }
in on
sessionTD-Xwoa0U8QWB0d6rpuksEYWFS4rRgCTcA6
undefined
sessionTD-Xwoa0U8QWB0d6rpuksEYWFS4rRgCTcA6
Session {
cookie:
{ path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true } }
First session has userid but it gets lost immediately. If I refresh my webpage it appears again.
sessionmiddleware has the code to save express session defined in middleware file as-
const session = require('express-session')
const sessionMiddleware = session({
secret: 'secret123',
resave: true,
saveUninitialized: true
})
Can anyone please help how to save it very first time.

express.js sharing the session from websocket to http

I can't find a way how to read in the .get() block the specific session value, that was assigned in the .ws() block recently:
const express = require('express');
const app = express();
const ws = require('express-ws')(app);
const session = require('express-session');
app.use(session({secret: 'secret', resave: true, saveUninitialized: true}));
app.get('/', function(req, res) {
console.log(req.session.val) //undefined (would like to have "my value")
res.end("<script>var ws = new WebSocket(window.location.href.replace('http', 'ws')); ws.send(true);</script>");
})
.ws('/', function(ws, req) {
//trying to assign session
req.session.val = 'my value';
});
app.listen(80);
Please, help.

Resources