Sam
Sam

Reputation: 960

Passport Local Strategy with Custom Callback Never Works

I have struggled so much with Passport because the custom callback feature simply does not work. Here's how I initialize passport:

var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var bodyParser = require('body-parser');

// Set up passport
passport.use('local', new LocalStrategy({
    usernameField: 'userId',
    passwordField: 'password'
}, function (userId, password, cb) {
    users.findByUserId(userId, function (err, user) {
        if (err) {
            return cb(err);
        }
        if (!user) {
            return cb(null, false);
        } else {
            if (user.password !== password) {
                return cb(null, false);
            }
            return cb(null, user);
        }
    });
}));
passport.serializeUser(function (user, cb) {
    cb(null, user.userId);
});
passport.deserializeUser(function (id, cb) {
    users.findByUserId(id, function (err, user) {
        if (err) { return cb(err); }
        cb(null, user);
    });
});

Then, this is how it's SUPPOSED to log a user in when a user posts to '/login':

exports.tryLogin = function (req, res, next) {
    passport.authenticate('local', function(err, user, info) {
        if (err) { return res.status(500).json({ success : false, message : 'Internal server error: ' + err.message }); }
        if (!user) { return res.status(500).json({ success : false, message : 'user not found'}); }
        req.logIn(user, function(err) {
          if (err) { return res.status(500).json({ success : false, message : 'Internal server error: ' + err.message }); }
          return res.status(200).json({ success : true });
        });
      })(req, res, next);
}

Here's how I have to do it because it never detects the user. The 'user' in the above method is always undefined. I have to construct it from the request myself to get it to work:

exports.tryLogin = function (req, res, next) {
    var user = {
        userId: req.body.userId,
        password: req.body.password
    }
    req.logIn(user, function (err) {
        if (err) {
            return res.status(500).json({ success : false, message : 'Internal server error: ' + err.message });
        }
        return res.status(200).json({ success : true, message : 'authentication succeeded' });
    });
}

This works, but feels wrong because I'm never calling passport.authenticate. Is this ok or should I be banging my head against the wall trying to get the custom callback to work as defined in the documentation?

Sam

Upvotes: 1

Views: 970

Answers (1)

Krzysztof Sztompka
Krzysztof Sztompka

Reputation: 7204

Yes this is wrong approach.

This code means:

exports.tryLogin = function (req, res, next) {
    var user = {
        userId: req.body.userId,
        password: req.body.password
    }
    req.logIn(user, function (err) {
        if (err) {
            return res.status(500).json({ success : false, message : 'Internal server error: ' + err.message });
        }
        return res.status(200).json({ success : true, message : 'authentication succeeded' });
    });
}

that You do not check permissions, You practically login anybody without password check.

Upvotes: 1

Related Questions