Node.js和Passport对象没有方法validPassword

请注意,我是Node.js中的初学者,请耐心等待:)

我正在使用Node.js + Express 3 + Passport创build一个简单的身份validation(本地)只是为了玩耍

和我到目前为止,当一个错误的用户名或密码input用户被redirect到一个错误页面

但是当用户input正确的用户名和密码时,我得到这个错误

node_modules\mongoose\lib\utils.js:435 throw err; ^ TypeError: Object { _id: 50b347decfd61ab9e9e6768f, username: 'saleh', password: '123456' } has no method 'validPassword' 

我不确定那里有什么问题

app.js(我删除了不必要的代码):

  var passport = require('passport') , LocalStrategy = require('passport-local').Strategy; app.configure(function(){ app.set('port', process.env.PORT || 3000); app.set('views', __dirname + '/views'); app.set('view engine', 'ejs'); app.use(express.favicon()); app.use(express.logger('dev')); app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(passport.initialize()); app.use(passport.session()); app.use(app.router); app.use(express.static(path.join(__dirname, 'public'))); }); var mongoose = require('mongoose'); var db = mongoose.createConnection('localhost', 'authTest'); var authSchema = mongoose.Schema({ username: 'string', password: 'string' }); var User = db.model('users', authSchema); 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: 'Incorrect username.' }); } if (!user.validPassword(password)) { return done(null, false, { message: 'Incorrect password.' }); } return done(null, user); }); } )); passport.serializeUser(function(user, done) { done(null, user.id); }); passport.deserializeUser(function(id, done) { User.findById(id, function(err, user) { done(err, user); }); }); app.post('/login', passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login/error', }) ); 

现在在routes / login.js中

 var mongoose = require('mongoose'); var db = mongoose.createConnection('localhost', 'authTest'); var authSchema = mongoose.Schema({ username: 'string', password: 'string' }); var User = db.model('users', authSchema); exports.index = function(req, res){ User.find(function (err, list) { res.render('login', { title: 'Usernames and Passwords', users: list,msg:""}); }); }; 

谢谢你的时间。

那么,这是显而易见的,不是吗? 您正在使用

 if (!user.validPassword(password)) { return done(null, false, { message: 'Incorrect password.' }); } 

但是你还没有定义validPassword方法。 将其附加到您的模式:

 var authSchema = mongoose.Schema({ username: 'string', password: 'string' }); authSchema.methods.validPassword = function( pwd ) { // EXAMPLE CODE! return ( this.password === pwd ); }; 

编辑你也错误地定义了模式。 它应该是:

 var authSchema = mongoose.Schema({ username: String, password: String }); 

请注意, usernamepassword都应该是Stringtypes的对象,而不是string"string" ,如果你知道我的意思。 🙂

看起来像你从passportjs网站复制的例子,贾里德没有提到如何实现它..

在护照js github页面上,他有另一个(更简单)的例子; 他完全删除了validPassword方法(第18行):

 if (user.password != password) { return cb(null, false); } 

这就是我的应用程序(使用encryption)的基础上。

这也是一个小白菜,花了我整整一天的时间来找出这一个。 我使用了另一个Jared的示例应用程序的历史和一些来自这里的人的encryptionbuild议。

首先,我制作了一个生成盐的方法(一个大的随机数被串化),使用salt和用户的密码创build一个哈希(在nodejs的encryption模块的帮助下),最后存储salt并且每次在mongoose节省一个新的帐户之前散列。

 //make hash userSchema.pre('save', function(next) { var user = this; if(!user.isModified('password')) return next(); var rand = (Math.floor(Math.random() * 1000000000)).toString(36); var hash = crypto.createHash('md5').update(user.password + rand).digest("hex"); user.password = hash; user.salt = rand; next(); }); 

为了validation,我只需要input密码(在login时),并尝试使用盐重新做相同的散列。 然后我比较存储的哈希到新的,并相应地返回true或false。

  // Password verification userSchema.methods.validPassword = function(password) { var testhash = crypto.createHash('md5').update(password + this.salt).digest("hex"); if(testhash === this.password) { return true; } else { return false; } }