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.
Related
I have a node express application.
const session = require('express-session');
const config = require('config');
var MemoryStore = require('memorystore')(session);
module.exports = function (app) {
app.use(express.json());
app.use(
session({
saveUninitialized: false,
cookie: { maxAge: 86400000 },
store: new MemoryStore({
checkPeriod: 86400000
}),
resave: false,
secret: config.get('Storagehash')
})
);
app.use('/api/auth', users);
}
I have separated auth route and put it in a separate file like this. When I do console.log(req.session) I'm getting proper output.
const router = express.Router();
router.post('/', async (req, res) => {
....
req.session.isAuth = true;
console.log(req.session);
req.session.customerID = customer;
res.send(token);
}
But when I'm looking in the cookie tab, connect.sid is not getting inserted there.
Do you have a frontend application? If so, whenever you send a request to your backend you need to include withCredentials: true in your request. This will send the cookies to your backend. If you are using axios to make requests it can be done like this:
(Assuming your port is 5000)
axios.post("http://localhost:5000/api/auth/", {}, { withCredentials: true });
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);
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);
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
...
Trying to get sessions set up with Redis. I have my Redis DB in a dokku container, linked to my app (also in a dokku container). I keep getting a session undefined.I've stripped things back to the bare minimum, also checked the order in which things are run. I still get an undefined.
I've read here 'session' is undefined when using express / redis for session store and Express js session undefined to no avail.
I shouldn't need to use cookie-parser, as expression-session has cookie stuff in it, and the docs say cookie-parser can cause problems with expression-session.
var express = require('express');
var session = require('express-session');
var redisStore = require('connect-redis')(session);
var bodyParser = require('body-parser');
var app = express();
app.set('port', (process.env.PORT || 5000));
var redisURL = 'redis://xxxxx:1234567#bar-redis-foo:6379';
var store = new redisStore({ url: redisURL });
app.use(session({
secret: 'ssshhhhh',
store: store,
saveUninitialized: true,
resave: true
}));
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json()); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
app.get('/', function(req, res, next) {
console.log(req.session); // Logs Undefined
res.send('Hello');
});
Check your redis connection and run again. Sample code is following line.
"use strict";
const express = require("express");
const bodyParser = require("body-parser");
const session = require("express-session");
const RedisStore = require("connect-redis")(session);
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(session({
secret: "$kx(Fj$uB!Ug!#jCkguFmc6f7t<c-e$9",
resave: false,
saveUninitialized: true,
store: new RedisStore({
url: "redis://:********#pub-redis-12766.eu-central-1-1.1.ec2.redislabs.com:12766",
ttl: 5 * 60 // 5 minute (Session store time)
})
}));
app.use(function (request, response, next) {
let path = request.originalUrl;
if (request.session.user) {
request.session.reload(function (err) { //session expire time regenerate
if (!err) {
next();
} else {
response.redirect('/login');
}
});
} else {
if (path == '/login') {
next();
} else {
response.redirect('/login');
}
}
});
app.get('/', function(request, response) {
if (request.session.user) {
response.send(request.session.user);
} else {
response.redirect("/login");
}
});
app.get('/login', function(request, response) {
if (request.session.user) {
response.redirect("/");
} else {
request.session.user = {username: "halil"}; //custom key {user} and custom data {username: "halil"}
}
response.send('Login');
});
app.get('/logout', function(request, response) {
if (request.session.user) {
request.session.destroy();
response.redirect("/login");
} else {
response.redirect("/login");
}
});
app.listen(app.get('port'), function () {
console.log('App is working on port: ' + app.get('port'));
});