title: passport.js - authenticate users from MongoDB with passport-local
body: <p>I have a simple users collection in my MongoDB. I user mongo-native driver.</p>
  
  <pre><code>{
      "email": "johndow@example.com",
      "password": "123456",
      "_id": {
          "$oid": "50658c835b821298d3000001"
      }
  }
  </code></pre>
  
  <p>As I user auth via pair email:pass, I re-wrote default passport-local function findByUsername to this:</p>
  
  <pre><code>function findByEmail(email, fn) {
      db.collection("users", function(err, collection) {
          collection.find({}, {}, function(err, users) {
              users.each(function(err, user) {
                  if (user.email === email) {
                      return fn(null, user);
                  }
              });
              return fn(null, null);
          });
      });
  }
  </code></pre>
  
  <p>Just get all of the users form DB, and checking - if user.email == provided email, then return user object. </p>
  
  <p>I use _id parameter of MongoDB as id for users, that's why I've modifies these two functions:</p>
  
  <pre><code>passport.serializeUser(function(user, done) {
      done(null, user._id);
  });
  
  passport.deserializeUser(function(id, done) {
      findById(id, function(err, user) {
          done(err, user);
      });
  });
  </code></pre>
  
  <p>And this is my code for passport local strategy:</p>
  
  <pre><code>passport.use(new LocalStrategy( function(email, password, done) {
      process.nextTick(function() {
          console.log('initialize findByEmail() for "',email,'"');
          findByEmail(email, function(err, user) {
              if (err) {
                  return done(err);
              }
              if (!user) {
                  console.log('Unknown user ' + email)
                  return done(null, false, {
                      message: 'Unknown user ' + email
  
                  });
              }
              if (user.password != password) {
                  console.log('Invalid password')
                  return done(null, false, {
                      message: 'Invalid password'
                  });
              }
              //сonsole.log('ALL VERIFIATION PASSED');
              return done(null, user);
          })
      });
  }));
  </code></pre>
  
  <p>I post data from login page:</p>
  
  <pre><code>app.post('/login', passport.authenticate('local', {
      failureRedirect: '/',
      failureFlash: true
  }), function(req, res) {
      res.redirect('/desk');
  });
  </code></pre>
  
  <p>And I get</p>
  
  <pre><code>Error: Can't set headers after they are sent.
  </code></pre>
  
  <p>and after this I get</p>
  
  <pre><code>TypeError: Cannot read property 'email' of null
  </code></pre>
  
  <p>The last error is really strange 'cause findByEmail has console.log(user) line (removed from this listing) and it list all the user's data. </p>
  
  <p>What am I doing wrong?</p>