【问题标题】:ValidationError with Passport.jsPassport.js 的 ValidationError
【发布时间】:2018-04-23 16:50:39
【问题描述】:

我将首先提到我对编程、节点、js 非常陌生,尤其是一般的护照/身份验证。我不懈地搜索并在堆栈上发现了类似的问题,但无法根据我找到的答案制定解决方案。如果我的问题很长并且违反了任何礼仪,我深表歉意。

我知道用户输入值正确地从 ejs 表单传递到我的 authController 函数(我可以通过 req.body...在控制台中记录每个值)。我也知道我的数据库工作正常,因为我在其他区域访问过它。根据我的研究,我怀疑的一件事是密码可以作为对象传递,并且没有以某种方式正确序列化。话虽如此,在我的 app.js 文件中,我肯定会执行以下操作,我认为应该避免此问题:

var User = require('./models/users');
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

我收到以下错误:

ValidationError: User validation failed: user_password: Path `user_password` is required.

 message: 'Path `user_password` is required.',
    name: 'ValidatorError',
    properties: [Object],
    kind: 'required',
    path: 'user_password',
    value: undefined,
    reason: undefined,
    '$isValidatorError': true 

/models/users.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var passportLocalMongoose = require('passport-local-mongoose');

var UserSchema = new Schema(
  {
    first_name: {type: String, required: true, max:100},
    last_name: {type:String, required: true, max: 100},
    email_address: {type: String, required:true, max: 100},
    username: {type:String, required: true, max: 100},
    user_password: {type: String, required:true, max: 100}
  }
);

UserSchema.plugin(passportLocalMongoose);


module.exports = mongoose.model('User', UserSchema);

authController.js

userController.doRegister = function(req, res) {
  console.log(req.body.user_password);
  var newUser = new User({
    first_name: req.body.first_name,
    last_name: req.body.last_name,
    email_address: req.body.email_address,
    username: req.body.username
  });
  User.register(newUser, req.body.user_password, function(err, user) {
    if (err) {
      console.log(err);
      return res.render('register', { user : user });

    }

    passport.authenticate('local')(req, res, function () {
      res.redirect('/');

      console.log('reached end of doregister in auth contro');
    });
  });
};

注册.ejs

 <table>
            <tr><td>First Name</td><td><input type="text" name="first_name" ></td></tr>
            <tr><td>Last Name</td><td><input type="text" name="last_name" ></td></tr>
            <tr><td>Email Address</td><td><input type="text" name="email_address" ></td></tr>
            <tr><td>Username</td><td><input type="text" name="username" ></td></tr>
            <tr><td>Password</td><td><input type="text" name="user_password" ></td></tr>
            <tr><td colspan="3"><input type="submit" value="Register" ></td></tr>
        </table>

【问题讨论】:

    标签: javascript node.js authentication model-view-controller passport.js


    【解决方案1】:

    如我所见,您的错误可能与此有关:

    var newUser = new User({
        first_name: req.body.first_name,
        last_name: req.body.last_name,
        email_address: req.body.email_address,
        username: req.body.username
     });
    

    这里你应该有user_password

    var newUser = new User({
        first_name: req.body.first_name,
        last_name: req.body.last_name,
        email_address: req.body.email_address,
        username: req.body.username,
        user_password: req.body.user_password
    });
    

    由于这是必需的,因此您无法在没有它的情况下创建新用户。 更好的方法是处理 before save 中的密码,然后在其中进行哈希和验证。

    【讨论】:

    • 是或否,真正的登录问题不在这里。但你说的完全正确,应该有一个验证错误,因为user_password 是必填字段。
    • 他发布的错误是Mongoose ValidationError: ValidationError: User validation failed: user_password: Path user_password is required。
    • 同意。但这不是解决问题的正确方法。如果 OP 接受您的回答,那么问题仍然存在,它不会登录用户。显然,OP 并没有完全理解 passport 的工作原理,schema 中根本不应该有密码字段,而是应该由 passport-local-mongoose 添加。
    【解决方案2】:

    首先,您不想在架构中处理用户密码(即删除用户架构中的user_password)。这是不安全的,因为您没有对您的用户密码进行散列和加盐,这也是您要使用 passport 库的原因。由于显然您不想接触密码哈希和加盐,所以请让 passport-local-mongoose 为您完成。

    接下来,控制器中间件的真正问题是您没有将user mongoose 对象传递给req.loginpassport.authenticate('local', (err, authUser) =&gt; { (do_something) }) 是一个中间件,它为您提供经过身份验证的用户对象作为回调,但在您决定“登录”用户之前它不会填充 req.user 对象。所以你应该试试这个:

    userController.doRegister = function(req, res) {
      console.log(req.body.user_password);
    
      const newUser = new User({
        first_name: req.body.first_name,
        last_name: req.body.last_name,
        email_address: req.body.email_address,
        username: req.body.username
      });
    
      User.register(newUser, req.body.user_password, function(err, user) {
        if (err) {
          console.log(err);
          return res.render('register', { user : user });
        }
    
        req.login(user, err => {
          if (err) throw err;
          console.log('reached end of doregister in auth contro');
          return res.redirect('/');
        });
    
      });
    };
    

    注意:请不要使用var,因为我们现在有const

    【讨论】:

    • 非常感谢您的回复——非常有帮助。我在按预期编译之前所做的一项编辑是将 res.logIn 更改为 req.login。现在正在运行,再次感谢!
    猜你喜欢
    • 2013-07-16
    • 2018-11-05
    • 2015-02-15
    • 2022-07-13
    • 2019-01-12
    • 2017-05-10
    • 2018-10-07
    • 2019-11-11
    • 1970-01-01
    相关资源
    最近更新 更多