var mongoose = require('mongoose') , passport = require('passport') , LocalStrategy = require('passport-local').Strategy , SALT_WORK_FACTOR = 10; mongoose.connect('localhost', 'test'); var db = mongoose.connection; db.on('error', console.error.bind(console, 'connection error:')); db.once('open', function callback() { console.log('Connected to MongoDB'); }) // User schema var userSchema = mongoose.Schema({ username: { type: String, required: true, unique: true }, email: { type: String, required: true, unique: true }, password: { type: String, required: true, unique: true}, }); // Bcrypt middleware userSchema.pre('save', function(next) { var user = this; if (!user.isModified('password')) return next(); bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) { if (err) return next(err); bcrypt.hash(user.password, salt, function(err, hash) { if (err) return next(err); user.password = hash; next(); }); }); }); // Password verification userSchema.methods.comparePassword = function(candidatePassword, callback) { bcrypt.compare(candidatePassword, this.password, function(err, isMatch) { if (err) return callback(err); callback(null, isMatch); }); }; // Passport session setup. // To support persistent login sessions, Passport needs to be able to // serialize users into and deserialize users out of the session. Typically, // this will be as simple as storing the user ID when serializing, and finding // the user by ID when deserializing. passport.serializeUser(function(user, done) { done(null, user.id); }); passport.deserializeUser(function(id, done) { User.findById(id, function (err, user) { done(err, user); }); }); // Use the LocalStrategy within Passport. // Strategies in passport require a `verify` function, which accept // credentials (in this case, a username and password), and invoke a callback // with a user object. In the real world, this would query a database; // however, in this example we are using a baked-in set of users. passport.use(new LocalStrategy(function(username, password, done) { User.findOne({ username: username }, function(err, user) { if (err) return done(err); if (!user) { return done(null, false, { message: 'Unknown user ' + username }); } user.comparePassword(password, function(err, isMatch) { if (err) return done(err); if(isMatch) { return done(null, user); } else { return done(null, false, { message: 'Invalid password' }); } }); }); }));