I am using express session and MongoStore for storing session ID
Here is my app.js
var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
var passport = require('passport');
var flash = require('connect-flash');
var path = require('path');
var app = express();
var user = require('./models/userModel');
//------Connect to database
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost:27017/porto', { useMongoClient: true });
//------Config Passport
require('./config/passport.js')(passport);
//------Adding middlewares
app.use(bodyParser.urlencoded({extended:true}));
app.use(cookieParser());
app.use(session({
secret : 'secret',
saveUninitialized : true,
resave : true,
store : new MongoStore({mongooseConnection : mongoose.connection})
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
My route handler for posting a ToDo
app.post('/addTodo',function(req,res){
console.log(req.body);
console.log(req.user._id); // Here the user id is changed
console.log(req.sessionID); // Here the sessionID never changed, but assigned to the newly logged in user
var todo = req.body.todo;
userModel.update(
{ _id: req.user._id },
{ $push: { todos: todo } },
function(err,done){
if (err)
return err;
return done;
}
);
res.redirect('/profile');
});
Related
I know that there are numerous posts already referring to the same problem, however, I couldn't find a solution for my case. Here is the relevant code for the issue :
users.js (route)
The login form is submits a POST request to this route.
var express = require('express');
var router = express.Router();
// Require controllers
var usersController = require('../../controllers/usersController');
/* POST login */
router.post('/login', usersController.loginAccount);
module.exports = router;
usersController.js
The passport authentication is handled here.
req.isAuthenticated() returns false here as well. However, successRedirect is executed, which should mean that the user was successfully authenticated.
'use strict';
var bodyParser = require('body-parser');
var mysql = require('mysql');
var bcrypt = require('bcryptjs');
var Client = require('../models/Client');
var passport = require('passport');
var Sequelize = require('sequelize');
var urlencodedParser = bodyParser.urlencoded({ extended: false });
/* POST - Login */
module.exports.loginAccount = function (req, res, next) {
passport.authenticate('local', {
successRedirect: '../dashboard',
failureRedirect: '/users/login',
failureFlash: true
}) (req, res, next);
console.log("Exactly after authentication: " + req.isAuthenticated());
}
index.js (route)
Here, ensureAuthenticated always returns false
var express = require('express');
var router = express.Router();
// Require controllers
var indexController = require('../../controllers/indexController');
/* GET dashboard page */
router.get('/dashboard', ensureAuthenticated, indexController.dashboardPage);
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated())
{console.log("AUTHENTICATED"); return next();}
else{
console.log("NOT AUTHENTICATED");
req.flash('error_msg', 'Please log in to view this resource');
res.redirect('/users/login');
}
}
module.exports = router;
indexController.js
When submitting the login form, this code doesn't get executed, because ensureAuthenticated() is false.
'use strict';
var bodyParser = require('body-parser');
var mysql = require('mysql');
var urlencodedParser = bodyParser.urlencoded({ extended: false });
/* GET - Dashboard page */
module.exports.dashboardPage = function(req, res) {
// console.log(req.user);
// console.log(req.isAuthenticated());
res.render('dashboard');
};
passport.js
const LocalStrategy = require('passport-local').Strategy;
const Sequelize = require('sequelize');
const bcrypt = require('bcryptjs');
// Load User Model
const Client = require('../models/Client');
module.exports = function(passport) {
passport.use(
new LocalStrategy({ usernameField: 'username'}, function(username, password, done) {
// Match User
Client.findOne({ where: {username: username} })
.then(function(user) {
if(!user) {
return done(null, false, { message: 'That username is not registered'});
}
// Match password
bcrypt.compare(password, user.password, function(err, isMatch) {
if(err) throw err;
if(isMatch) {
return done(null, user);
} else {
return done(null, false, { message: 'Password incorrect'});
}
});
})
.catch(function(err) { console.log(err) });
})
)
passport.serializeUser(function(user, done) {
console.log('Serializing user');
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
console.log('Deserializing user');
console.log('User ID:', id);
Client.findByPk(id)
.then(function(err, user) {
console.log('User ID:', id);
done(err, user);
});
});
}
All the required middleware is setup in the correct order (express-session -> passport.initialize -> passport.session). cookieParser and express-session are set with the same secret (which is otherwise a problem as other posts suggest).
app.js
var createError = require('http-errors');
var express = require('express');
var expressLayouts = require('express-ejs-layouts');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var mysql = require('mysql');
var flash = require('connect-flash');
var session = require('express-session');
var passport = require('passport');
var bodyParser = require('body-parser');
var cors = require('cors');
// Passport config
require('./config/passport')(passport);
var usersController = require('./controllers/usersController');
var indexRouter = require('./api/routes/index');
var usersRouter = require('./api/routes/users');
var roomsRouter = require('./api/routes/rooms');
var app = express();
app.use(cors());
// view engine setup
app.set('views', path.join(__dirname, 'views'));
// EJS
app.use(expressLayouts);
app.use(express.json());
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser('secret'));
app.use(express.static(path.join(__dirname, 'public')));
// Express Session
app.use(session({
secret: 'secret',
resave: true,
saveUninitialized: true,
cookie: { maxAge: 60000 }
}));
// Passport middleware
app.use(passport.initialize());
app.use(passport.session());
In your app.js the routes need to be defined after the passpor middleware is set up.
For Example:
var createError = require('http-errors');
var express = require('express');
var expressLayouts = require('express-ejs-layouts');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var mysql = require('mysql');
var flash = require('connect-flash');
var session = require('express-session');
var passport = require('passport');
var bodyParser = require('body-parser');
var cors = require('cors');
// Passport config
require('./config/passport')(passport);
var usersController = require('./controllers/usersController');
var app = express();
app.use(cors());
// view engine setup
app.set('views', path.join(__dirname, 'views'));
// EJS
app.use(expressLayouts);
app.use(express.json());
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser('secret'));
app.use(express.static(path.join(__dirname, 'public')));
// Express Session
app.use(session({
secret: 'secret',
resave: true,
saveUninitialized: true,
cookie: { maxAge: 60000 }
}));
// Passport middleware
app.use(passport.initialize());
app.use(passport.session());
var indexRouter = require('./api/routes/index');
var usersRouter = require('./api/routes/users');
var roomsRouter = require('./api/routes/rooms');
Try doing this and see the output
I am implementing a simple login functionality and storing the data in the express-session but not able to get it back.
In loginDb.js file in login function i am storing the userId in session variable and in getLoginStatus function i am trying to access the userId but it is returing as undefined.
I have gone through many post related to similar issue but nothing helped in my case. Don't know what i am doing wrong here. Below is the code.
server.js
var express = require('express');
var pg = require('pg');
var cookieParser = require('cookie-parser');
var bodyparser = require('body-parser');
var session = require('express-session');
var path = require('path');
const port = 3000;
const loginroute = require('./Routes/login');
var app=express();
app.use(bodyparser.json());
app.use(bodyparser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({
secret: 'This is a secret',
resave: true,
saveUninitialized:true,
cookie: {
secure: false,
maxAge: 60000
}
}));
//Routes
app.use('/api/loginroute',loginroute);
app.listen(port,function(){
console.log('app listening to port:'+port);
});
login.js
const express = require('express');
const router = express.Router();
const db = require('../DataAccessLayer/loginDb');
router.get('/getLoginStatus', db.getLoginStatus);
router.post('/login', db.login);
module.exports = router;
loginDb.js
var config = require('../Config/config');
var session = require('express-session');
var pg = require('pg');
var pool = new pg.Pool(config.development.db);
function getLoginStatus(req, res, next){
var userId = req.session.userId;
};
function login(req, res, next) {
pool.connect(function(err, client, done) {
if (err) {
console.log("not able to get connection "+ err);
res.status(400).send(err);
}
var q = "select id from nodetest.users where name=$1 and password=$2";
client.query(q, [req.body.username, req.body.password], function(err, result) {
done();
if(err) {
return console.error('error running query', err);
}
if(result.rowCount>0){
req.session.userId = result.rows[0].id;
}
res.send(result.rows);
});
});
};
module.exports = {
login:login,
getLoginStatus:getLoginStatus
};
Set cookieParser secret key similar as that of express-session secret key will fix the issue.
app.use(cookieParser('This is a secret'))
Doc Says
Using cookie-parser may result in issues if the secret is not the same
between this module and cookie-parser.
I'm new to Node JS and I'm trying to store session in mongoDB by using the connect-mongo npm package , once I add the following line - i get an error :
app.use(session({
saveUninitialized: true,
resave: true,
store : new MongoStore({ // adding this will cause an error
db: 'users'
})
}));
Here are the session parts of my code (i'm using express 4.16) :
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var expressValidator = require('express-validator');
var multer = require('multer');
var upload = multer({dest: './uploads'});
var flash = require('connect-flash');
var bcrypt = require('bcryptjs');
var mongo = require('mongodb');
var mongoose = require('mongoose');
var MongoStore = require('connect-mongo')(session);
var db = mongoose.connection;
session(app, mongo.initSessionStore);
app.use(session({
saveUninitialized: true,
resave: true,
store : new MongoStore({
db: 'users'
})
}));
// Passport
app.use(passport.initialize());
app.use(passport.session());
You haven't sent instance of MonogDB to MongoStore. You sent string 'user', and it expect database instance. So it can't connect to MonogDB.
If you are using Mongoose you need first to connect to database, and then you can usemongoose.connection for MongoStore:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var db = mongoose.connection;
app.use(session({
saveUninitialized: true,
resave: true,
store : new MongoStore({
mongooseConnection: db
})
}));
I want to pass my passport variable to my router class but can't seem to find out how to do this.
Server.js:
const session = require('express-session');
const path = require('path');
const passport = require('passport');
const routes = require('./routes')(passport); //pass variable here
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const mongoose = require('mongoose');
const configDB = require('./config/database.js');
const flash = require('connect-flash');
const app = express();
mongoose.connect(configDB.url);
app.use(express.static(path.join(__dirname, '/dist')));
app.use(cookieParser());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(session({
name: 'sessionid',
secret: 'changethis',
resave: false,
saveUninitialized: true,
cookie: {secure: true}
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use(routes);
app.listen(8080, function () {
console.log('App started on port 8080');
});
/routes/index.ejs: (I want the passport variable here).
const routes = require('express').Router();
const path = require('path');
const api = require('./api');
routes.use('/api', api);
routes.get('/*', function (req, res) {
res.sendFile(path.join(path.dirname(require.main.filename) + '/dist/index.html'));
});
module.exports = routes;
What do I need to do in the index.ejs to get the passport variable?
You need to changes your /routes/index.ejs to export factory function.
const path = require('path');
const api = require('./api');
module.exports = function factory(yourVar) {
const routes = require('express').Router();
routes.use('/api', api);
routes.get('/*', function (req, res) {
res.sendFile(...);
});
return routes;
}
I am trying to reuse the database object.The session intialization is working fine outside the Mongoconnect callback. But when I move it inside the call back , the session cookie is not being set in the browser . Any ideas??
var express=require('express');
var bodyParser=require('body-parser');
var cookieParser=require('cookie-parser');
var session=require('express-session');
var mongodb=require('mongodb'),
MongoClient = mongodb.MongoClient;
var MongoStore = require('connect-mongo')(session);
var util=require('util');
var assert=require('assert');
var db;
var app=express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
app.use(cookieParser());
MongoClient.connect('mongodb://localhost:27017/mydb',function(err,database){
if(!err)
{
app.use(session(
{ name:'sessionCookie',secret:'secret',saveUninitialized:true,resave:true ,
store: new MongoStore({ db:database })
}
));
app.listen(3000);
}
});
This seems to be a timing issue between the time the app object is intialized aand the session is intilaized. I chnaged the code a bit and the issue seems to be fixed. I am not entirely sure about the root cause. Feel free to chip in
var express=require('express');
var bodyParser=require('body-parser');
var cookieParser=require('cookie-parser');
var session=require('express-session');
var mongodb=require('mongodb'),
MongoClient = mongodb.MongoClient;
var MongoStore = require('connect-mongo')(session);
var util=require('util');
var assert=require('assert');
var db;
var app;
MongoClient.connect('mongodb://localhost:27017/mydb',function(err,database){
if(!err)
{
app=express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
app.use(cookieParser());
app.use(session(
{ name:'sessionCookie',secret:'secret',saveUninitialized:true,resave:true ,
store: new MongoStore({ db:database })
}
));
app.listen(3000);
}
});