Node.js 如何在mongoose+;表达
当我尝试从exports.index.post运行user.comparePassword时,出现以下错误(请参见下文)——我粘贴了所有代码以帮助缩小问题范围。UserSchema.pre('save')方法工作正常,但不是./routes/account.js中的方法(我使用的是mongoose 3) 这是我得到的错误Node.js 如何在mongoose+;表达,node.js,mongodb,express,mongoose,Node.js,Mongodb,Express,Mongoose,当我尝试从exports.index.post运行user.comparePassword时,出现以下错误(请参见下文)——我粘贴了所有代码以帮助缩小问题范围。UserSchema.pre('save')方法工作正常,但不是./routes/account.js中的方法(我使用的是mongoose 3) 这是我得到的错误 Caught exception: [TypeError: Object { username: 'test4', email: 'test4@test.com', p
Caught exception: [TypeError: Object { username: 'test4',
email: 'test4@test.com',
password: '$2a$10$Ix5vCuVYGIU7AmXglmfIxOyYnF6CiPJfw9HLSAGcRDxMJEttud/F6',
_id: 505fee7ce28f10711e000002,
__v: 0 } has no method 'comparePassword']
## ./app.js
app.post('/account', routes.account.index.post);
## ./models/user.js
var mongoose = require('mongoose')
, bcrypt = require('bcrypt')
, Schema = mongoose.Schema
, db = mongoose.createConnection('localhost', 'mydb');
var UserSchema = new Schema({
username : { type: String, required: true, index: { unique: true }, trim: true }
, email : { type: String, required: true, index: { unique: true }, trim: true, lowercase: true }
, password : { type: String, required: true, trim: true }
});
UserSchema.pre('save', function(next) {
var user = this;
// only hash the password if it has been modified (or is new)
if (!user.isModified('password')) return next();
// generate a salt
bcrypt.genSalt(function(err, salt) {
if (err) return next(err);
// hash the password along with our new salt
bcrypt.hash(user.password, salt, function(err, hash) {
if (err) return next(err);
// override the cleartext password with the hashed one
user.password = hash;
next();
});
});
});
//compare supplied password
UserSchema.methods.comparePassword = function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
if (err) return cb(err);
cb(null, isMatch);
});
};
module.exports = db.model('User', UserSchema);
##./routes/account.js
/*
* GET account home page.
*/
exports.index = {};
exports.index.get = function(req, res){
var d = { title: 'Edit account' };
res.render('account', { d: d } );
};
exports.index.post = function(req, res){
req.assert('email', 'Enter email').notEmpty().isEmail();
req.assert('password', 'Enter password').notEmpty().isAlphanumeric().len(5,20);
//user must confirm password
if ( req.body.password_new ) {
req.assert('password_new', 'Enter password').notEmpty().isAlphanumeric().len(5,20);
req.assert('password_new_confirm', 'Passwords must match').equals(req.body.password);
}
res.locals.err = req.validationErrors(true);
if ( res.locals.err ) {
var d = { title: 'Edit account' };
res.render('account', { d: d } );
return;
}
var User = require('../models/user')
, mongoose = require('mongoose')
, db = mongoose.createConnection('localhost', 'mydb');
var user = db.model('User', User.UserSchema);
user.find({username: req.session.user.username }, function(err, user){
if ( err ) return next(err);
/*********** THIS IS WHERE THE ERROR OCCURS **************/
user.comparePassword(req.body.password, function(err, isMatch) {
console.log("isMatch", isMatch);
if (err) next(err);
if (!isMatch) {
req.flash('error', 'Woops, looks like you mistyped your password.');
req.session.user = user;
res.locals.user = user;
res.redirect('/account');
return;
}
//user is authenticated
//session length
console.log(req.body);
});
});
};
user.find
查询0个或多个文档,因此其回调的第二个参数是文档数组,而不是单个文档user.findOne
查询0或1个文档,因此其回调的第二个参数为null或单个文档。因此,您试图在JavaScript数组
上调用模式的方法,这当然行不通。将该find
调用更改为findOne
,它应该可以工作。似乎无法从.find()使用方法,只能从.findOne()使用方法。您知道是否可以从用户内部获取用户对象。comparePassword()调用?@chovy在类似comparePassword
的实例方法中,this
是调用它的用户文档。在定义中,this
是一个用户对象,但当我在异步行为中调用它时,this
给我的是模式,而不是回调中的用户对象user.comparePassword(req.body.password,function(err,isMatch){//cannotgetuserhere})
@chovy您已经有了用户
,因为您刚刚使用它来调用比较密码
。这是可以直接访问回调的。好吧,我不知道为什么以前我失败了,正如你所说的那样。