TypeError: User.comparePassword is not a function, can't login or register users

TypeError: User.comparePassword is not a function, can't login or register users

我正在尝试比较用户注册和登录时使用的密码,但出现以下错误:

TypeError: User.comparePassword is not a function
at /home/ubuntu/workspace/app.js:51:10
at Query.<anonymous> (/home/ubuntu/workspace/node_modules/mongoose/lib/model.js:4038:16)
at /home/ubuntu/workspace/node_modules/kareem/index.js:273:21
at /home/ubuntu/workspace/node_modules/kareem/index.js:131:16
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickCallback (internal/process/next_tick.js:104:9)

comparePassword()所在的用户模型

var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");
var bcrypt = require("bcrypt-nodejs");

var UserSchema = new mongoose.Schema({
    username: {type: String, unique: true, required: true},
    password: {type: String, unique: true, required: true},
    // avatar: String,
    firstName: String,
    lastName: String,
    email: {type: String, unique: true, required: true},
    resetPasswordToken: String,
     resetPasswordExpires: Date,
    // isAdmin: {type: Boolean, default: false}
});

UserSchema.plugin(passportLocalMongoose);

//save function -- hashes and then saves the password
UserSchema.pre('save', function(next) {
  var user = this;
  var SALT_FACTOR = 5;

  if (!user.isModified('password')) return next();

  bcrypt.genSalt(SALT_FACTOR, function(err, salt) {
    if (err) return next(err);

    bcrypt.hash(user.password, salt, null, function(err, hash) {
      if (err) return next(err);
      user.password = hash;
      next();
    });
  });
});

//compares and checks 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 = mongoose.model("User", UserSchema);

这是它传递给的 app.js 文件:

var express = require("express"),
    app = express(),
    bodyParser = require("body-parser"),
    mongoose = require("mongoose"),
    expressSanitizer = require("express-sanitizer"),
    passport = require("passport"),
    cookieParser = require("cookie-parser"),
    LocalStrategy = require("passport-local"),
    session = require("express-session"),
    nodemailer = require("nodemailer"),
    bcrypt = require("bcrypt-nodejs"),
    async = require("async"),
    crypto = require("crypto"),
    flash = require("connect-flash"),
    moment = require("moment"),
    User = require("./models/user"),
    // seedDB      = require("./seeds"),
    methodOverride = require("method-override");


// APP CONFIG
mongoose.connect("mongodb://localhost/blog", {useMongoClient: true});
//PRODUCTION CONFIG - LIVE URL GOES HERE!

app.set("view engine", "ejs");
app.use(express.static(__dirname + "/assets"));
app.use(bodyParser.urlencoded({extended: true}));
app.use(expressSanitizer());
app.use(methodOverride("_method"));
app.use(cookieParser('secret'));
//require moment
app.locals.moment = require('moment');
// seedDB(); //seed test data!


// PASSPORT CONFIGURATION
app.use(require("express-session")({
    secret: "It's a secret to everyone!!",
    resave: false,
    saveUninitialized: false
}));

app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
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.' });
    console.log(user);
    User.comparePassword(password, function(err, isMatch) {
      if (isMatch) {
        return done(null, user);
      } else {
        return done(null, false, { message: 'Incorrect password.' });
      }
    });
  });
}));
passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  User.findById(id, function(err, user) {
    done(err, user);
  });
});



app.use(function(req, res, next){
   res.locals.currentUser = req.user;
   res.locals.success = req.flash('success');
   res.locals.error = req.flash('error');
   next();
});

每当我注册或尝试登录时,我都会收到 comparePassword is not a function 错误。

这是我的 mongo 数据库,其中一个用户名为 "apple"

{ "_id" : ObjectId("5a2ec9ff5e64680bdd930330"), "salt" : "398d81d059440847480ae8f31c20c3e21c3a1b522ba57dbeed6f8cfa9fddf1b7", "hash" : "3270b089ac910853e07c40bdb1e71a948ccfee378b9d92936a50f53f6f4e02f79bdb6cc611c0e15a5c8dbdded8c165b30c86597ce202d47af89859ef074f093ecc4bfe9419fe406ee067ba60fdc97acda4934ae95160b29a9e6fa57b288ddad7c4fe84e459d165256084c8af9399d0258f93d24068e03e0b5cef704c3c115b78944c98b8c431bdb3d6314803f30af318f135316277050f71897f0009e1509da0634fe1bbf6c80bfb66a9d175061544e28d33f7573780e7be576db409b8950fb79d63b40aa34bea8919bf81afd46bddd866e1eab4fa447ba26af137f4bf01559b6632084b9d04677671f85b9b5ec4fe4eaf088c1023fb512a93e546dcab1571ec02217594cba2894a5468f41b4935f976d79587d47f16bb4ef00566ded4a0b349cda6f442fd5b11e325e1feb651d3c367b5943d22ed32e6ec14065bea58cb6fbd55bf13daab2b183bb6ab59f150a64b99304ce7b163621753d69377cc394c8d5ec9c2e30ef6ab50f32e8241c542a01950d3e16c1d83aa6986a67aac96e9652270919bd05e6994493b89326857bf9ac75a450a39ba79f2af0035354e40bd32c43f9acc7e660158ca17e3d7e66673ab8950a63126fa0f6f7206de71bef0c3f212022b5f6eaee49775c2750e8ac068b98566bf6fe643c935e6dac531b9a5b12ace19c850ec369f431432b7a2d0817097f3762244ee8db1f30c0814bcbcaf8b6ab77c", "username" : "apple", "firstName" : "apple", "email" : "apple@gmail.com", "password" : "a$lkr5htZwOBVSIMJSQXveduEKmx6/AnN7jUxTjDSDKr3UQ0DqaQzrS", "__v" : 0 }
> 

尝试使用小写用户:

user.comparePassword(password, function(err, isMatch) {
  if (isMatch) {
    return done(null, user);
  } else {
    return done(null, false, { message: 'Incorrect password.' });
  }
});