首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是否有必要使用joi和mongoose验证相同的模式,以防止未经验证的数据插入?

是否有必要使用joi和mongoose验证相同的模式,以防止未经验证的数据插入?
EN

Stack Overflow用户
提问于 2019-03-21 03:34:43
回答 2查看 945关注 0票数 1

我的问题是,为了防止未经验证的数据插入,是否需要使用joi和mongoose进行双重验证,或者是否不必要,只会使我的性能下降?我想防止joi的验证可能存在错误,如果发生这种情况,未经验证的数据将被插入到MongoDb中。对此最好的实践是什么?

我的代码:

Product.js:

代码语言:javascript
运行
复制
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:

代码语言:javascript
运行
复制
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中。

这里最好的是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-21 04:49:08

您必须使用适当的JOI函数来验证数据。如果你使用,标准是使用中间件https://www.npmjs.com/package/express-joi-validation,它会抛出一个错误,并且不会在控制器中执行代码。而且不要在端点处理程序中进行验证,使用中间件,否则事情会变得混乱!最棒的是,你只需要传递你的JOI对象,包就会处理响应。

票数 1
EN

Stack Overflow用户

发布于 2019-10-29 18:39:40

你可以试试Joigoose。您可以创建一个Joi Schema并将其传递给Mongoose,如下所示:

代码语言:javascript
运行
复制
new Mongoose.Schema(Joigoose.convert(joiUserSchema));

我已经用了一段时间了,没有任何问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55268886

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档