passport.initialize() middleware not in use for express 4.10 for custom callback

abarik picture abarik · Apr 13, 2015 · Viewed 12.8k times · Source

can anyone please help me with this. I keep getting Error: passport.initialize() middleware not in use when i try connecting to a user that is in the database. Exception cases work just fine (e.i incorrect password/username not found).

Here is the setup:

versions i am using

// version
node --version v0.10.33
[email protected]
[email protected]
[email protected]

server.js code is here

// server.js
'use strict';
var express = require('express');
var bodyParser = require('body-parser');
var session = require('express-session');
var passport = require('passport');
var flash = require('connect-flash');
var cookieParser = require('cookie-parser');

//Our custom modules
var mysqlc = require('./modules/mysql_client');

// Our custom apps
var app = express();

//view engine setup
app.set('env', process.env.NODE_ENV);
console.log('Running as environment: ' + app.get('env'));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(favicon(path.join(__dirname,'./public/favicon.ico')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/rootpath', express.static(path.join(__dirname,'./public')));

// use session/cookie for auth
app.use(cookieParser());
app.use(session({ 
    secret: 'clinksecret',  // TODO: STORE outside
    saveUninitialized: true,
    resave: true
}));

// use connect-flash for flash messages stored in session
app.use(flash());

var server = require('http').Server(app);
var io = require('socket.io')(server);

/**
 * Connect to all servers 1st
 * */

// mysqlc connection setup
var connPropMySqlC = {
        connectionLimit : 10,
        host            : config.settings.auth.clink.host,
        user            : config.settings.auth.clink['user'],
        password        : config.settings.auth.clink['password'],
        database        : config.settings.auth.clink.database
};
var mydbc = new mysqlc.MySqlClient(connPropMySqlC);
mydbc.connect(function (err) {
    if (err) {
        console.error('server-mdbc-connect-ERROR:', err);
        throw err;
    }
});

//authentication with session after connection to mydbc
var passport = require('./modules/auth')({mydbc:mydbc, io:io, app:app, passport:passport});
app.use(passport.initialize());
app.use(passport.session());

/*
 * routers
 * */
var testapp = require('./testapp/app')({mydbc:mydbc, io:io});
app.use('/testapp', testapp);

auth.js (all the passport configs)

// auth.js
/**
 * for user authentication using passport
 */
var LocalStrategy = require('passport-local').Strategy;
var bcrypt   = require('bcrypt-nodejs');

//Variables local to module
var io;
var mydbc;
var app;
var passport;

function validPassword(val, hash, callback) {
    return bcrypt.compare(val, hash, callback);
}

function exportModFunc(args) {
    /**
     * used to passing object across modules
     * @param {object} args: args = {mydbc, io} // where mydbc mysqlc.MySqlClient object
     * @return {object} passport
     */
    mydbc = args.mydbc; // update variable
    io = args.io;       // update variable
    app = args.app;    // update variable
    passport = args.passport;   // update variable

    // route middleware
    passport.use('local-login', new LocalStrategy({
        usernameField : 'formLogin_user',
        passwordField : 'formLogin_password',
        passReqToCallback : true // allows us to pass back the entire request to the callback
    },
    function(req, username, password, done) {
        mydbc.getUser({'username':username}, function(err, user) {
            console.log('test-local-login', username, password, done, err, user)
            if (err)
                return done(err);

            // if no user is found, return the message
            if (!user)
                return done(null, false, req.flash('loginMessage', 'No user found.')); // req.flash is the way to set flashdata using connect-flash

            // if the user is found but the password is wrong
            validPassword(password, user.password, function(err, res) {
                if (err)
                    return done(err);

                if (!res) {
                    return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata
                } else {
                    // all is well, return successful user
                    return done(null, user);
                }
            });
        });
    }));

    passport.serializeUser(function(user, done) {
        /**
         * each session will serialize to userid
         * http://passportjs.org/guide/configure/
         * @param {object} user: same as object as returned by mydbc.getUser()
         * @return {null} null
         */
        done(null, user.userid);
    });

    passport.deserializeUser(function(userid, done) {
        /**
         * each session will deserialize to user
         * http://passportjs.org/guide/configure/
         * @param {int} userid: same as mydbc.getUser().userid
         * @return {null} null
         */
        mydbc.getUser({'userid':userid}, function(err, user) {
            done(null, user);
        });
    });

    // route post request
    //// process the login form
    app.post('/authLogin/', function(req, res, next) {
        passport.authenticate('local-login', function(err, user, info) {
            if (err) { return next(err); }
            var errors = {};
            var loginMsg = req.flash('loginMessage');
            if (loginMsg.length !== 0 || (!user)) {
                errors.loginMsg = loginMsg;
                return res.json({
                    errors: errors
                });
            }
            console.log('test-authLogin-local-login', err, user, info);
            req.logIn(user, {failureFlash: true}, function(err) {
                if (err) { return next(err); }
                return res.redirect('/users/' + user.username);
            });
        })(req, res, next);
    });

    return passport;
};

module.exports = exportModFunc;

Answer

olan picture olan · Apr 13, 2015

You should initialize passport before adding it to your route middleware: http://passportjs.org/guide/configure/

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

//authentication with session after connection to mydbc
var passport = require('./modules/auth')({mydbc:mydbc, io:io, app:app, passport:passport});

You are also redefining your passport var in server.js which is unnecessary.