Authentication issue in Nodejs: ValidationError: Path `password` is required

Authentication issue in Nodejs: ValidationError: Path `password` is required

我在尝试注册新用户时遇到错误 ValidationError: Path password is required。我是 Node、编程和身份验证的新手。

这是我的代码,然后我将逐步介绍我所做的一切以尝试解决问题。

用户模型和架构

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();
});


// REQUIRE ROUTES
var commentRoutes = require("./routes/comments"),
    bpostRoutes = require("./routes/bposts"),
    indexRoutes = require("./routes/index");


//USE ROUTES
app.use("/", indexRoutes);
app.use("/bposts", bpostRoutes);
app.use("/bposts/:id/comments", commentRoutes);


//RUN SERVER
app.listen(process.env.PORT, process.env.IP, function(){
   console.log("The Server Has Started!");
});

这里是index.js发布新用户的路由文件

// handle sign up logic

router.post("/register", function(req, res) {

    var newUser = new User({
        username: req.sanitize(req.body.username),
        firstName:req.sanitize(req.body.firstName),
        lastName: req.sanitize(req.body.lastName),
        email: req.sanitize(req.body.email),
    });
   console.log(newUser);

    // if (req.body.adminCode === 'secretcode123') {
    //     newUser.isAdmin = true;
    // }

    User.register(newUser, req.body.password, function(err, user) {
        if (err) {
            console.log(err);
            return res.render("register", { error: err.message });
        }
        passport.authenticate("local")(req, res, function() {
            req.flash("success", "Successfully Signed Up! Nice to meet you " + req.body.username);
            res.redirect("/bposts");
        });
    });
});

如您在 index.js

中所见

我做了一个 console.log(newUser),它带回了整个 newUser 对象。

{ username: 'apple',
      firstName: 'apple',
      lastName: 'apple',
      email: 'apple@gmail.com',
      _id: 5a2eac41720dc60acffa02f4 }

除此之外,我不确定我还能做哪些其他测试来定位幕后发生的事情。任何关于将来如何思考此类问题以便我自己解决的帮助或指示都会很棒。谢谢。

这里还有完整的 StackTrace,如果有帮助的话:

  { ValidationError: User validation failed: password: Path `password` is required.
    at MongooseError.ValidationError.inspect (/home/ubuntu/workspace/node_modules/mongoose/lib/error/validation.js:57:23)
    at formatValue (util.js:351:36)
    at inspect (util.js:185:10)
    at exports.format (util.js:71:24)
    at Console.log (console.js:43:37)
    at /home/ubuntu/workspace/routes/index.js:35:21
    at /home/ubuntu/workspace/node_modules/passport-local-mongoose/index.js:213:33
    at /home/ubuntu/workspace/node_modules/mongoose/lib/model.js:4038:16
    at /home/ubuntu/workspace/node_modules/mongoose/lib/services/model/applyHooks.js:175:17
    at _combinedTickCallback (internal/process/next_tick.js:73:7)
    at process._tickCallback (internal/process/next_tick.js:104:9)
  errors: 
   { password: 
      { ValidatorError: Path `password` is required.
          at MongooseError.ValidatorError (/home/ubuntu/workspace/node_modules/mongoose/lib/error/validator.js:25:11)
          at validate (/home/ubuntu/workspace/node_modules/mongoose/lib/schematype.js:782:13)
          at /home/ubuntu/workspace/node_modules/mongoose/lib/schematype.js:829:11
          at Array.forEach (native)
          at SchemaString.SchemaType.doValidate (/home/ubuntu/workspace/node_modules/mongoose/lib/schematype.js:789:19)
          at /home/ubuntu/workspace/node_modules/mongoose/lib/document.js:1528:9
          at _combinedTickCallback (internal/process/next_tick.js:73:7)
          at process._tickCallback (internal/process/next_tick.js:104:9)
        message: 'Path `password` is required.',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'required',
        path: 'password',
        value: undefined,
        reason: undefined,
        '$isValidatorError': true } },
  _message: 'User validation failed',
  name: 'ValidationError' }

基本上您在模型中定义了需要密码。

var UserSchema = new mongoose.Schema({
    username: {type: String, unique: true, required: true},
    password: {type: String, unique: true, required: true}, // <-- See here
    firstName: String,
    lastName: String,
    email: {type: String, unique: true, required: true},
    resetPasswordToken: String,
    resetPasswordExpires: Date
});

但是当你保存时你并没有传递密码:

var newUser = new User({
    username: req.sanitize(req.body.username),
    firstName:req.sanitize(req.body.firstName),
    lastName: req.sanitize(req.body.lastName),
    email: req.sanitize(req.body.email),
    /* password: req.sanitize(req.body.password) // <- Probably missing something like this.*/
});

我没有写以下博客,但我认为它可能对您有所帮助。

https://github.com/DDCreationStudios/Writing/blob/master/articles/AuthenticationIntro.md#user-registration

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

您进行护照身份验证的方式,不需要在用户模式中具有所需的密码。 如果密码丢失,Passport 将自动检查密码。如果密码丢失,护照将抛出错误。因此无需将密码设置为 true,因为护照将在内部完成相同的工作。这对我有用。

user.js

    var userSchema=new mongoose.Schema({
    username:{type:String,required:true},
    email:{type:String,required:true},
    password:String
    });

server.js

app.post("/signUp",(req,res)=>{
    User.register(new User({username:req.body.username,email:req.body.email}),req.body.password,(err,user)=>{
        if(err){
            console.log(err);
        }else{
            passport.authenticate("local")(req,res,()=>{
                res.redirect("/");
            });
        }
    });
});