我的父模式定义如下:
User.js:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var PasswordSchema = require('./Password');
var UserSchema = new Schema({
name: { type: String, required: true },
password: PasswordSchema
});
mongoose.model('User', UserSchema);
我的孩子架构定义如下:
Password.js:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var crypto = require('crypto');
var PasswordSchema = new Schema ({
_id: false,
hashedPassword: { type: String, required: true },
salt: { type: String, default: '' }
});
var passwordRegex = /^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,24}$/;
PasswordSchema.virtual('password')
.set(function (password) {
if (passwordRegex.test(password))
{
this.invalidate('password', 'Invalid password format');
}
});
mongoose.model('Password', PasswordSchema);
module.exports = PasswordSchema;
现在我在控制器中使用了这些模型架构,如下所示:
user.js的:
require('../models/User');
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var User = mongoose.model('User');
var Password = mongoose.model('Password');
router.post('/register', function (req, res, next) {
var user = new User(req.body);
var password = new Password({ password: 'abcd1234' });
console.log(password.$__.validationError.errors['hashedPassword']); // Here it works I got the validation error
user.password = password;
user.password.$__.validationError = password.$__.validationError; // WORKAROUND
console.log(user.password.$__.validationError.errors['hashedPassword']); // Here it doesn't work no validation error anymore ...
user.save(function (err) {
if (err)
console.log(":(");
else
console.log(":)");
});
});
module.exports = router;
问题:
所以我现在的问题是,无论我发送给我的孩子的密码是什么,它都不会使该过程无效。我如何使虚拟儿童的猫鼬保存动作无效?还有其他更好的选择吗?
问题已更新:
在user.js中,为什么变量密码有验证错误,当我将其分配给user.password时,我不再有验证错误了?我该如何纠正?
**更新2:**
我找到了一个解决方法,参见user.js:我只是分配了必需的属性来生成验证错误。但看起来真的不干净还有另一种方式吗?
答案 0 :(得分:1)
这是一个很好的例子https://gist.github.com/swaj/1350041,重构如下
PasswordSchema.virtual('password')
.get(function(){
return this._password;
})
.set(function (password) {
this._password = password;
// invoke crypto to hash and encrypt password, then assign it to hashedPassword
this.hashedPassword = password; // this is just for test
});
PasswordSchema.path('hashedPassword').validate(function(v) {
if (v) {
if (passwordRegex.test(v)) {
this.invalidate('password', 'Invalid password format');
}
}
if (!v) {
this.validate('password', 'password required');
}
}, null);
测试代码
var user = new User({name: 'dd'});
user.password = new Password({password: 'asdfASF123444'});
user.save(function (err) {
if (err)
console.log(err);
else
console.log("save user successfully");
});
验证错误
{ [ValidationError: User validation failed]
message: 'User validation failed',
name: 'ValidationError',
errors:
{ password:
{ [ValidatorError: Invalid password format]
properties: [Object],
message: 'Invalid password format',
name: 'ValidatorError',
kind: 'user defined',
path: 'password',
value: undefined } } }
Document.prototype.invalidate = function (path, err, val) {
if (!this.$__.validationError) {
this.$__.validationError = new ValidationError(this);
}
// ...
我们知道invalidate
函数属于Document
。
password.$__.validationError.errors['hashedPassword']
您为validation
定义PasswordSchema
,而不是UserSchema
。所以user.password.$__.validationError.errors['hashedPassword']
无效。
使用
测试代码var user = new User({name: 'dd'});
user.password = new Password({password: 'asdfwe32113'});
user.save(function (err) {
if (err)
console.log(err);
else
console.log("save user successfully");
});
但是,使用此代码
将触发验证`user.password = new Password({hashedPassword: 'asdfwe32113'});`
不会触发此验证。
因为对于virtual
field,只更新了正确的虚拟名称字段,因此可以调用.set
函数。
另请将这些代码添加到virtual('password')
,以确保hashedPassword
可以正确设置。
if (passwordRegex.test(password)) {
this.invalidate('password', 'Invalid password format');
}else {
this.hashedPassword = password;
}
对于第二个问题,必须在require('../models/User');
之前调用mongoose.model()
,以确保首先解析User.js
,并将User
添加到mongoose.model
中在User.js
中。因此user.js
可以从mongoose中找到这个User
模型。 JavaScript是一种解释的编程语言,因此我们应该以这种方式告诉JS引擎文件解析顺序。