Ad

Passport.js SerializeUser And DesializeUser Are Not Being Called Ever?

Having an issue with Passport-local. It appears neither serializeuser nor deserializeUser get called. After reading other posts on SO, it seems a lot of people who had this issue were not including bodyParser.

Here is my app.js:

var express = require('express');
var app = 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 db_config = require('./config/database');
var mongoose = require ('mongoose');

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

//loads passport implementation
require('./config/passport')(app);

//loads all routes
require('./config/routes')(app);

// 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 handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  //initialize connection to database
  mongoose.connect(db_config.development);

  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// development error handler
// will print stacktrace
if (app.get('env') === 'test') {
  //initialize connection to database
  mongoose.connect(db_config.test);

  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

if(app.get('env') === 'production'){
  //initialize connection to database
  mongoose.connect(db_config.production);

  // production error handler
  // no stacktraces leaked to user
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: {}
    });
  });
}

module.exports = app;

Here is config/passport.js:

module.exports = function(app){
  var passport = require ('passport');
  var LocalStrategy = require('passport-local').Strategy;
  var session = require('express-session');
  var User = require('../models/user.js');
  // =========================================================================
  // passport session setup ==================================================
  // =========================================================================
  // required for persistent login sessions
  // passport needs ability to serialize and unserialize users out of session

  // used to serialize the user for the session
  passport.serializeUser(function(user, done) {
    console.log('serialize');
    done(null, user._id);
  });

  // used to deserialize the user
  passport.deserializeUser(function(id, done) {
    console.log('deserialize');
    User.findById(id, function(err, user) {
      done(err, user);
    });
  });

  //configure passport http-basic strategy
  passport.use(new LocalStrategy({
    usernameField: "username",
    passwordField: "password"
  },
  function(username, password, done){
    User.findOne({username: username}, function(err, user){
      if(err) return done(err);
      if(!user || !user.validatePassword(password)) return done(null, false);
      console.log("inside LocalStrategy: " + user);
      return done(null, user);
    });
  }));

//setup express-session
app.use(session({
  secret: "secret",
  saveUninitialized: true,
  resave: true
}));

app.use(passport.initialize());
app.use(passport.session());

return passport;
};

Here is my routes.js:

module.exports = function(app){
  var routes = require('../routes/index');
  var users = require('../routes/users');
  var walks = require('../routes/walks');

  var isAuthenticated = function(req, res, next){
    if(req.isAuthenticated())
      next();
    res.status(401).send('You must login first.');
  };

  app.use('/', routes);
  app.all('*', isAuthenticated);
  app.use('/users', users);
  app.use('/walks', walks);
};

Here is the routes/index.js:

var router = require('express').Router();
var passport = require('passport');
var controller = require('../controllers/index');

router.get('/', controller.index);

router.post('/signup', controller.signup);

router.post('/login', passport.authorize('local'), controller.login);

module.exports = router;

And finally here is the controller/index.js:

var User = require('../models/user.js');
var handleError = require('../handlers/error');
var controller = {};

controller.index = function(req, res, next) {
  res.render('index', { title: 'Express' });
};

controller.signup = function(req, res){
  console.log(req.body);
  var user = new User();
  user.username = req.body.username;
  user.password = req.body.password;

  user.save(function(err, user){
    if(err) {
      console.log(err.code);
      handleError(res, err);
    }
    return res.send(user);
  });
};

controller.login = function(req, res){
  console.log('inside /login');
  console.log('req.user: ' + req.user);
  console.log('req.session: ');
  console.log(req.session);
  console.log('req.body: ');
  console.log(req.body);
  res.send(req.user);
};

module.exports = controller;

In POSTMAN I am first creating a user with a POST request to /signup with:

{
 "username": "bob",
 "password": "password123"
}

Then I POST to /login with the same credentials, here is the output:

inside LocalStrategy: { __v: 0,
  username: 'bob',
  password: '$2a$10$Oa/Q9C5Elsoa0P4427P6fOXWIKerlD937FYgLFrwCWwXxGW1gbsoW',
  _id: 5685d6845c7b208693b71091 }
inside /login
req.user: undefined
req.session:
Session {
  cookie:
   { path: '/',
     _expires: null,
     originalMaxAge: null,
     httpOnly: true } }
req.body:
{ username: 'bob', password: 'password123' }
POST /login 200 205.704 ms - -

As you can see, the console.log() in both serializeUser and deserializeUser do not get called. Why is this? I'm at a complete loss here, I honestly have no idea what else to try.

Ad

Answer

This:

router.post('/login', passport.authorize('local'), controller.login);

Should be this:

router.post('/login', passport.uter.post('/login', passport.authenticate('local'), controller.login);

passport.authorize() is meant for connecting third-party authorization responses to already-authenticated users.

Ad
source: stackoverflow.com
Ad