我正在尝试使用之前注册的电子邮件阻止注册。我试图在mongoose架构中创建自定义验证。但它给了我一个错误 ValidationError:用户验证失败 在MongooseError.ValidationError 。代码下降了。有人可以告诉我错误在哪里或更好的方法来检查db中是否存在用户电子邮件。
// user schema
var UserSchema = mongoose.Schema({
username: {
type: String,
index: true,
require: true
},
password: {
type: String,
require: true
},
email: {
type: String,
lowercase: true,
trim: true,
index: {
unique: true,
},
validate: {
validator : isEmailExists, msg: 'Email already exists'
}
},
name: {
type: String
},
admin: Boolean,
active: Boolean,
});
// validation
function isEmailExists(email, callback) {
if (email) {
mongoose.models['User'].count({ _id: { '$ne': this._id }, email: email }, function (err, result) {
if (err) {
return callback(err);
}
callback(!result);
})
}
}
// createUser function
module.exports.createUser = function(newUser, callback){
bcrypt.genSalt(10, function(err, salt) {
bcrypt.hash(newUser.password, salt, function(err, hash) {
newUser.password = hash;
newUser.save(callback);
});
});
}
路由器
router.post('/register', function(req, res, next) {
var name = req.body.name;
var email = req.body.email;
var password = req.body.password;
var confirmedPassword = req.body.confirmedPassword;
// Validation
req.checkBody('name', 'Name is required').notEmpty();
req.checkBody('email', 'Email is required').notEmpty();
req.checkBody('email', 'Email is not valid').isEmail();
req.checkBody('password', 'Password is required').notEmpty();
req.checkBody('confirmedPassword', 'Passwords do not match').equals(req.body.password);
var errors = req.validationErrors();
if (errors) {
res.render('register', {
errors: errors
});
} else {
var newUser = new User({
name: name,
email: email,
password: password,
admin: false,
active: false
});
User.createUser(newUser, function (err, user) {
if (err) {
throw err;
}
});
req.flash('success_msg', 'You are registerd and can now login');
res.redirect('/users/login');
}
答案 0 :(得分:1)
检查数据库中是否已存在电子邮件ID的最佳方法是使用express-validator。 由于升级到版本4,因此API已更改。 现在,而不是使用: -
const expressValidator = require('express-validator');
..在你的app.js文件中,然后调用中间件。相反,只需在用户路径文件中执行此操作: -
const { check, validationResult } = require('express-validator/check');
现在,要检查数据库中是否已存在电子邮件ID,您必须使用Promise。这是一个有效的代码: -
router.post('/register', [
check('name')
.not()
.isEmpty()
.withMessage('Name is required'),
check('email')
.not()
.isEmpty()
.withMessage('Email is required')
.isEmail()
.withMessage('Invalid Email')
.custom((value, {req}) => {
return new Promise((resolve, reject) => {
User.findOne({email:req.body.email}, function(err, user){
if(err) {
reject(new Error('Server Error'))
}
if(Boolean(user)) {
reject(new Error('E-mail already in use'))
}
resolve(true)
});
});
}),
// Check Password
check('password')
.not()
.isEmpty()
.withMessage('Password is required'),
// Check Password Confirmation
check('confirmedPassword', 'Passwords do not match')
.exists()
.custom((value, { req }) => value === req.body.password)
], function(req, res) {
var name = req.body.name;
var email = req.body.email;
var password = req.body.password;
var confirmedPassword = req.body.confirmedPassword;
// Check for Errors
const validationErrors = validationResult(req);
let errors = [];
if(!validationErrors.isEmpty()) {
Object.keys(validationErrors.mapped()).forEach(field => {
errors.push(validationErrors.mapped()[field]['msg']);
});
}
if(errors.length){
res.render('register',{
errors:errors
});
} else {
var newUser = new User({
name: name,
email: email,
password: password,
admin: false,
active: false
});
User.createUser(newUser, function (err, user) {
if (err) {
throw err;
}
});
req.flash('success_msg', 'You are registerd and can now login');
res.redirect('/users/login');
}
您也可以这样做以检查用户名。 Here is the link to the official GitHub page of express-validator
答案 1 :(得分:1)
您可以使用email-check
软件包来检查用户是否先前已注册(email
字段中是否有重复的电子邮件地址)。
这是下载软件包的链接
https://www.npmjs.com/package/email-check
通过在模型中写入unique: true
属性,将提供不重复的邮件地址。但是,您还应该包括email-chack
验证,您可以在路由器
import emailCheck from "email-check";
//other imports
router.post("/register", (req, res) => {
var name = req.body.name;
var email = req.body.email;
var password = req.body.password;
var confirmedPassword = req.body.confirmedPassword;
// your validation for another fields
emailCheck(email)
.then(() => {
User.create(req.body)
.then(() => {
res.send(req.body);
})
.catch((error) =>
res.json({serverErrorDublicateEmail: "The email address is already subscribed. Please try to use another one or simply Log in"});
});
})
.catch(() => {
res.json({serverErrorEmailExistence: "The email address doesn't exist. Please try the valid one"});
});
});
emailCheck
返回承诺。注意:我正在使用ES6语法。
就这样。您的UserSchema
可以保留而无需任何验证。
答案 2 :(得分:1)
您可以使用Monsgoose的Model.findOne()=> https://mongoosejs.com/docs/api.html#model_Model.findOne:
router.post('/register',(req,res)=>{
// Object destructuring
const {username,password,email,...rest} =req.body;
// Error's Array
let errors = [];
// Mongoose Model.findOne()
User.findOne({email:email}).then(user=>{
if(user){
errors.push({msg: 'Email already exists'});
res.render('register',{errors})
}
})
})