Daniel Daniel - 1 month ago 5
Node.js Question

How can I write this in such a way where I get the desired result?

So I looked at this documentation:

Documentation for "ensureAuthentication" "isAuthenticated" passport's functions?

And this one:

https://www.jokecamp.com/tutorial-passportjs-authentication-in-nodejs/

And unfortunately neither have helped in figuring out why the passport middleware is not giving me the desired result which is, to log in a registered user and be redirected to the members page, instead it just redirects to the same login page and does not allow the logged in user to go to the members page, a feature that should only happen when the user is logged out.

This is index.js in routes folder:

var express = require('express');
var router = express.Router();

// Members Page
router.get('/', ensureAuthenticated, function(req, res, next) {
res.render('index', { title: 'Members' });
});

function ensureAuthenticated(req, res, next){
if(req.isAuthenticated()){
return next();
}
res.redirect('/users/login');
}

module.exports = router;


And this is the users.js page in routes folder:

var express = require('express');
var router = express.Router();
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/user');

/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});

router.get('/register', function(req, res, next) {
res.render('register',{
'title': 'Register'
});
});

router.get('/login', function(req, res, next) {
res.render('login',{
'title': 'Login'
});
});

router.post('/register', function(req, res, next){
// Get Form Values
var name = req.body.name;
var email = req.body.email;
var username = req.body.username;
var password = req.body.password;
var password2 = req.body.password2;

// Check for Image Field
if(req.files && req.files.profileimage){
console.log('Uploading File...');

// File Info
var profileImageOriginalName = req.files.profileimage.originalname;
var profileImageName = req.files.profileimage.name;
var profileImageMime = req.files.profileimage.mimetype;
var profileImagePath = req.files.profileimage.path;
var profileImageExt = req.files.profileimage.extension;
var profileImageSize = req.files.profileimage.size;
} else {
// Set a Default Image
var profileImageName = 'noimage.png';
}

// Form Validation
req.checkBody('name','Name field is required').notEmpty();
req.checkBody('email','Email field is required').notEmpty();
req.checkBody('email','Email not valid').isEmail();
req.checkBody('username','Username field is required').notEmpty();
req.checkBody('password','Password field is required').notEmpty();
req.checkBody('password2','Passwords do not match').equals(req.body.password);

// Check for Errors
var errors = req.validationErrors();

if(errors){
res.render('register',{
errors: errors,
name: name,
email: email,
username: username,
password: password,
password2: password2
});
} else {
var newUser = new User({
name: name,
email: email,
username: username,
password: password,
profileimage: profileImageName
});

// Create User

User.createUser(newUser, function(err, user){
if(err) throw err;
console.log(user);
});

User.createUser(newUser, function(err, user){
if(err) throw err;
console.log(user);
});

// Success Message
req.flash('success', 'You are now registered and may log in');

res.location('/');
res.redirect('/');
}
});

passport.serializeUser(function(user, done) {
done(null, user.id);
});

passport.deserializeUser(function(id, done) {
User.getUserByUsername(id, function(err, user) {
done(err, user);
});
});

passport.use(new LocalStrategy(
function(username, password, done){
User.getUserByUsername(username, function(err, user){
if(err)throw err;
if(!user){
console.log('Unknown User');
return done(null, false,{message: 'Unknown User'});
}

User.comparePassword(password, user.password, function(err, isMatch){
if(err) throw err;
if(isMatch){
return done(null, user);
} else {
console.log('Invalid Password');
return done(null, false, {message: 'Invalid Password'});
}
});
});
}
));

router.post('/login', passport.authenticate('local', {failureRedirect: '/users/login', failureFlash:'Invalid username or password'}), function(req, res){
console.log('Authentication Successful');
req.flash('success', 'You are logged in');
res.redirect('/');
});

router.get('/logout', function(req, res){
req.logout();
req.flash('success', 'You have logged out');
res.redirect('/users/login');
});


module.exports = router;

Answer

It seems that you misspelled something in line 102 which is your deserializeUser function. Rather than using User.getUserByUsername, you should use User.getUserById.

passport.deserializeUser(function(id, done) {
  User.getUserById(id, function(err, user) {
    done(err, user);
  });
});

This link goes to a related stackoverflow question. The best answer there says that the variable id corresponds to the user object created by the 'done' keywords in the functions. So what you thought was a username being entered in the function by NodeJS is actually just a unique key.

Comments