我的问题是,是否需要双重验证,包括使用joi和mongoose来防止未验证的数据插入,或者是否出于工作目的,只会让我失去性能? 我想防止joi的验证出现错误, 如果发生这种情况,则未经验证的数据将插入到MongoDb中。 最好的做法是什么?
我的代码:
Product.js:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const model = mongoose.model;
const ProductSchema = new Schema({
name: {
type: String,
minlength: 5,
maxlength: 50,
required: true,
validate: [{
validator: async name => await Product.where({ name }).countDocuments() === 0,
message: ({ value }) => `El nombre del producto: ${value} ya esta cogido.` // TODO: security
},
{
validator: async function(value) {
const regex = /^[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ]{1}[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ\s]{3,48}[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ]{1}$/;
return await regex.test(value);
},
message: 'solo letras y numeros, sin espacio al principio y al final' // TODO: security
},
]
},
description: {
type: String,
minlength: 30,
maxlength: 250,
required: true,
validate: {
validator: async function(value) {
const regex = /^[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ]{1}[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ\s]{28,248}[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ]{1}$/;
return await regex.test(value)
},
message: 'solo letras y numeros, sin espacio al principio y al final' // TODO: security
}
},
shortDescription: {
type: String,
minlength: 20,
maxlength: 100,
required: true,
validate: {
validator: async function(value) {
const regex = /^[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ]{1}[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ\s]{18,98}[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ]{1}$/;
return await regex.test(value)
},
message: 'solo letras y numeros, sin espacio al principio y al final' // TODO: security
}
},
tags: [{
type: String,
requirer: true,
validate: {
validator: async function(value) {
const regex = /^[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ]{1}[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ\s]{3,98}[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ]{1}$/;
return await ((value && value.length > 4) && (regex.test(value)));
},
message: 'El producto tiene que tener como minimo un tag y cada tag min 5 caracteres solo letras y numeros, sin espacio al principio y al final.' // TODO: security
}
}],
price: {
type: Number,
min: 30,
required: true,
validate: {
validator: async val => await (
val.isInteger && val >= 30
),
message: ({ value }) => `El precio del producto: ${value} es invalido, tiene que ser positivo y mayor o igual a 30` // TODO: security
}
},
create_At: { type: Date, default: Date.now }
});
const Product = model('Product', ProductSchema);
exports.Product = Product;
ProductJoiValidation:
const Joi = require('joi');
const nameSchema = Joi.string().min(5).max(50).regex(/^[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ]{1}[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ\s]{3,48}[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ]{1}$/).label("Nombre del producto").options({
language: {
string: {
regex: {
base: "El nombre del producto no puede contener espacios ni al principio ni al final, solo caracteres alfanumericos"
}
}
}
});
const descriptionSchema = Joi.string().min(30).max(250).regex(/^[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ]{1}[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ\s]{28,248}[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ]{1}$/).label("Descripcion del producto").options({
language: {
string: {
regex: {
base: "La descripcion del producto no puede contener espacios ni al principio ni al final, solo caracteres alfanumericos"
}
}
}
});
const shortDescriptionSchema = Joi.string().min(20).max(100).regex(/^[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ]{1}[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ\s]{18,98}[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ]{1}$/).label("Descripcion corta del producto").options({
language: {
string: {
regex: {
base: "La descripcion del producto no puede contener espacios ni al principio ni al final, solo caracteres alfanumericos"
}
}
}
});
const tagsSchema = Joi.array().items(Joi.string().min(5).regex(/^[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ]{1}[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ\s]{3,98}[a-zA-Z0-9ÁÉÍÓÚñáéíóúÑ]{1}$/)).min(1).label("tags").options({
language: {
string: {
regex: {
base: "Los tags del producto no puede contener espacios ni al principio ni al final, solo caracteres alfanumericos"
}
}
}
});
const priceSchema = Joi.number().integer().positive().min(30);
const createProductSchema = Joi.object().keys({
name: nameSchema.required(),
description: descriptionSchema.required(),
shortDescription: shortDescriptionSchema.required(),
tags: tagsSchema.required(),
price: priceSchema.required()
});
function validateCreateProduct(createProduct) {
return Joi.validate(createProduct, createProductSchema, { abortEarly: false });
};
module.exports = {
validateCreateProduct
}
我想防止joi的验证出现错误, 如果发生这种情况,未经验证的数据将插入到MongoDb中。
这里最好的是什么?
答案 0 :(得分:1)
您可以尝试Joigoose。您创建一个Joi Schema并将其传递给Mongoose,例如:
new Mongoose.Schema(Joigoose.convert(joiUserSchema));
我已经使用了一段时间,没有问题。
答案 1 :(得分:0)
您必须使用适当的JOI函数来验证数据。如果使用,则标准是使用中间件https://www.npmjs.com/package/express-joi-validation,该中间件会引发错误并且不会在控制器中执行代码。并且不要在端点处理程序中进行验证,而要使用中间件,否则事情会变得混乱!很棒的事情是,您只需要传递您的JOI对象,程序包将负责响应。