I've spent more time than I'd like to admit scouring countless posts online that have the same problem as me, to no avail. The majority of solutions seemed to be things like not including
passReqToCallback: true
in my LocalStrategy.passport.serializeUser()
and passport.deserializeUser()
in my init file.app.use(passport.initialize())
and app.use(passport.session())
in app.js.app.use(cookieParser())
in app.js.passport.authenticate
within my page route.My login.js is as follows;
var LocalStrategy = require('passport-local').Strategy;
var User = require('../../models/user');
var bCrypt = require('bcrypt-nodejs');
module.exports = function(passport) {
passport.use('login', new LocalStrategy({passReqToCallback: true},
function(req, username, password, done) {
//Queries MongoDB For User
User.findOne({'username': username}, function(err, user) {
//In The Event Of An Error, Throw It
if (err) {
return done(err);
}
//Username Does Not Exist, Log Error, Callback, Flash Error Message
if (!user){
console.log('User: '+ username + ", does not exist.");
return done(null, false, req.flash('message', 'User Not found.'));
}
//User Exists, But Password Is Incorrect
if (!isValidPassword(user, password)){
console.log('Invalid Password');
return done(null, false, req.flash('message', 'Invalid Password')); // redirect back to login page
}
//If No Previous Error Conditions Are Met - Username/Password Are Correct
console.log("Validated User: " + username + ".");
//req.user = user;
return done(null, user);
}); //End of User.findOne()
}) //End of new LocalStrategy
); //End of passport.use()
/*
var isValidPassword = function(user, password){
return bCrypt.compareSync(password, user.password);
}
*/
//Passwords are not currently hashed in my DB, so ignore bcrypt for now.
var isValidPassword = function(user, password) {
return user.password == password;
}
}
My passport-init.js file
var login = require('./login');
var User = require('../../models/user');
module.exports = function(passport){
//Serialise User
passport.serializeUser(function(user, done) {
console.log("Serializing User: " + user.username + "\n" + user + ".");
done(null, user._id);
});
//De-Serialise User
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
console.log("Deserializing User: " + user.username + "\n" + user);
done(err, user);
});
});
//Setting up Passport Strategy for Login
login(passport);
}
My index.js file contains the POST Login route
/* POST Login Page*/
router.post('/login', passport.authenticate('login', {
successRedirect: '/dashboard',
failureRedirect: '/login',
failureFlash: true
}));
And dashboard.js contains all the routing for /dashboard/other-pages. These ones are protected by the isAuthenticated
function.
var express = require('express');
var router = express.Router();
var database = require('../public/javascripts/db-connect.js');
var isAuthenticated = function(req, res, next) {
console.log("User: " + req.user);
console.log("Authenticated?: " + req.isAuthenticated());
if (req.isAuthenticated()) {
return next();
} else {
res.redirect('/unauthorised');
}
}
module.exports = function(passport) {
//Routes /dashboard --> dashboard.pug
router.get('/', isAuthenticated, function(req, res, next) {
database.getData("busdata", function(err, data) {
if (err) {
console.error(err);
} else {
res.render('dashboard', {title: 'Dashboard', busdata: data});
}
});
});
//Routes /dashboard/journeys --> journeys.pug
router.get('/journeys', isAuthenticated, function(req, res, next) {
database.getData("journeydata", function(err, data) {
if (err) {
console.error(err);
} else {
res.render('journeys', {title: 'Journey Graphs', journeydata: data});
}
});
});
return router;
}
So when I run the app;
localhost:3000/dashboard
and localhost:3000/dashboard/journeys
. They correctly re-direct me to /unauthorised
./login
.Validated User: TomPlum.
Meaning passport.use()
reached return done(null, user)
Serialising User: TomPlum + the objects properties
POST /login 302 time ms
User: undefined
from isAuthenticated
isAuthenticated? false
GET /dashboard 302 time ms
Deserialising User: TomPlum + the objects properties
/unauthorised
as isAuthenticated()
evaluates to false.Why is req.user undefined
? Should I be using a LocalStrategy if my MongoDB is not-local? (Amazon Atlas Server). Other forum posts have suggested it could be a cookie issue but I've included the relevant cookie-parser
includes in my app.js
file.
app.js is here in-case it's an order issue.
//Require Variables
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');
//Mongo DB Connection Settings
var dbConfig = require('./db'); //db.js contains DB URL
var mongoose = require('mongoose');
mongoose.connect(dbConfig.url); //dbConfig.url refers to the export in db.js
//Page Routing
//var index = require('./routes');
var users = require('./routes/users');
var dashboard = require('./routes/dashboard')(passport);
var app = express();
app.d3 = require('d3');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public/images', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser('urban_sensing'));
app.use(express.static(path.join(__dirname, 'public')));
//app.use('/', index);
app.use('/dashboard', dashboard);
app.use('/users', users);
//Configuring Passport
var passport = require('passport');
var expressSession = require('express-session');
app.enable('trust-proxy');
app.use(expressSession({
secret: 'urban_sensing',
resave: true,
saveUninitialized: true,
proxy: true,
cookie: {
secure: true,
maxAge: 3600000
}
}));
app.use(passport.initialize());
app.use(passport.session());
//Flash Messaging For Passport
var flash = require('connect-flash');
app.use(flash());
//Initialize Passport
var initPassport = require('./public/javascripts/passport-init');
initPassport(passport);
var index = require('./routes/index')(passport);
app.use('/', index);
//Catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
//Error Handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Some of the app.use(expressSession({..}));
properties may currently be unnecessary as they've been added in an attempt to fix the issue.
Any help would be appreciated.
After too much time on this, turns out it was simply the order of app.js.
By moving
var dashboard = require('./routes/dashboard')(passport);
app.use('/dashboard', dashboard);
below all the passport configuration. It now works correctly. It seems that something wasn't initialised correctly during the routing of /dashboard when it was before the passport code.
Updated app.js
//Require Variables
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');
//Mongo DB Connection Settings
var dbConfig = require('./db'); //db.js contains DB URL
var mongoose = require('mongoose');
mongoose.connect(dbConfig.url); //dbConfig.url refers to the export in db.js
//Page Routing
//var index = require('./routes');
var users = require('./routes/users');
var app = express();
app.d3 = require('d3');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public/images', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser('urban_sensing'));
app.use(express.static(path.join(__dirname, 'public')));
//app.use('/', index);
app.use('/users', users);
//Configuring Passport
var passport = require('passport');
var expressSession = require('express-session');
app.use(expressSession({
secret: 'urban_sensing',
resave: false,
saveUninitialized: true,
cookie: {
maxAge: 3600000 //1 Hour
}
}));
app.use(passport.initialize());
app.use(passport.session());
//Flash Messaging For Passport
var flash = require('connect-flash');
app.use(flash());
//Initialize Passport
var initPassport = require('./public/javascripts/passport-init');
initPassport(passport);
var dashboard = require('./routes/dashboard')(passport);
app.use('/dashboard', dashboard);
var index = require('./routes/index')(passport);
app.use('/', index);
//Catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
//Error Handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments