Nodejs中的身份验证问题:ValidationError:路径`密码`是必需的

时间:2017-12-11 16:55:32

标签: passport.js passport-local

我收到错误ValidationError:尝试注册新用户时需要路径password。我是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' }

3 个答案:

答案 0 :(得分:2)

您进行护照身份验证的方式,不需要用户架构中所需的密码为真。 如果密码丢失,Passport 会自动检查密码。如果密码丢失,passport 会报错。因此无需使所需的密码为真,因为护照将在内部完成相同的工作。这对我有用。

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:-1)

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