我正在使用 node.js 我已经可以从注册 html 页面发布。但是下面的代码
exports.login = function (req, res, next) {
if (req.body && req.body.email && req.body.password) {
var userLogin = new User ({
email: req.body.email,
password: req.body.password
});
userLogin.findOne(function(err) {
if (!err) {
res.redirect('/about.html');
} else {
res.redirect('http://google.com');
next(err);
}
});
} else {
next(new Error('Incorrect POST'));
}
};
我遇到的问题是 userLogin.findOne 没有工作,因为它说 findOne 未定义。
链接到的 model.js 文件是:
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
bcrypt = require('bcrypt-nodejs'),
SALT_WORK_FACTOR = 10;
// these values can be whatever you want - we're defaulting to a
// max of 5 attempts, resulting in a 2 hour lock
MAX_LOGIN_ATTEMPTS = 5,
LOCK_TIME = 2 * 60 * 60 * 1000;
var UserSchema = new Schema({
email: { type: String, required: true, lowercase:true, index: { unique: true } },
password: { type: String, required: true },
firstName: {type: String, required: true},
lastName: {type: String, required: true},
phone: {type: Number, required: true},
birthday: {type: Date, required: true},
loginAttempts: { type: Number, required: true, default: 0 },
lockUntil: { type: Number }
});
UserSchema.virtual('isLocked').get(function() {
// check for a future lockUntil timestamp
return !!(this.lockUntil && this.lockUntil > Date.now());
});
//password hashing middleware
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(SALT_WORK_FACTOR, function(err, salt) {
if (err) return next(err);
// hash the password along with our new salt
bcrypt.hash(user.password, salt, null, function(err, hash) {
if (err) return next(err);
// override the cleartext password with the hashed one
user.password = hash;
next();
});
});
});
//password verification
UserSchema.methods.comparePassword = function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
if (err) return cb(err);
cb(null, isMatch);
});
};
UserSchema.methods.incLoginAttempts = function(cb) {
// if we have a previous lock that has expired, restart at 1
if (this.lockUntil && this.lockUntil < Date.now()) {
return this.update({
$set: { loginAttempts: 1 },
$unset: { lockUntil: 1 }
}, cb);
}
// otherwise we're incrementing
var updates = { $inc: { loginAttempts: 1 } };
// lock the account if we've reached max attempts and it's not locked already
if (this.loginAttempts + 1 >= MAX_LOGIN_ATTEMPTS && !this.isLocked) {
updates.$set = { lockUntil: Date.now() + LOCK_TIME };
}
return this.update(updates, cb);
};
// expose enum on the model, and provide an internal convenience reference
var reasons = UserSchema.statics.failedLogin = {
NOT_FOUND: 0,
PASSWORD_INCORRECT: 1,
MAX_ATTEMPTS: 2
};
UserSchema.statics.getAuthenticated = function(email, password, cb) {
this.findOne({ email: email }, function(err, user) {
if (err) return cb(err);
// make sure the user exists
if (!user) {
return cb(null, null, reasons.NOT_FOUND);
}
// check if the account is currently locked
if (user.isLocked) {
// just increment login attempts if account is already locked
return user.incLoginAttempts(function(err) {
if (err) return cb(err);
return cb(null, null, reasons.MAX_ATTEMPTS);
});
}
// test for a matching password
user.comparePassword(password, function(err, isMatch) {
if (err) return cb(err);
// check if the password was a match
if (isMatch) {
// if there's no lock or failed attempts, just return the user
if (!user.loginAttempts && !user.lockUntil) return cb(null, user);
// reset attempts and lock info
var updates = {
$set: { loginAttempts: 0 },
$unset: { lockUntil: 1 }
};
return user.update(updates, function(err) {
if (err) return cb(err);
return cb(null, user);
});
}
// password is incorrect, so increment login attempts before responding
user.incLoginAttempts(function(err) {
if (err) return cb(err);
return cb(null, null, reasons.PASSWORD_INCORRECT);
});
});
});
};
module.exports = mongoose.model('User', UserSchema);