我将在前面提到我对编程,节点,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');
});
});
};
register.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>
答案 0 :(得分: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中处理密码,在那里您进行哈希并验证它。
答案 1 :(得分:0)
首先,您不希望在架构中处理用户密码(即删除用户架构中的user_password
)。这是不安全的,因为你没有哈希和盐你的用户密码,这也是你想使用 passport 库的原因。很明显你不想触摸密码哈希和盐渍,所以请让 passport-local-mongoose 为你做。
接下来,您的控制器中间件中的真正问题是您没有将user
猫鼬对象传递给req.login
。 passport.authenticate('local', (err, authUser) => { (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
。