【问题标题】:Validation with MongooseJS causing NodeJS app to crash使用 MongooseJS 进行验证导致 NodeJS 应用程序崩溃
【发布时间】:2020-05-19 05:53:14
【问题描述】:

我正在尝试找到一种更好的方法来执行此验证。我有用户 schmea 设置,我试图让年龄验证正常工作,以免导致应用程序崩溃。您必须原谅我,因为我对这门语言还比较陌生,所以我可能不会 100% 解释它。但是,这是我创建的用户模式。

const mongoose = require('mongoose')
const validator = require('validator')
const bcrypt = require('bcryptjs')
const jwt = require('jsonwebtoken')

const userSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true,
        trim: true
    },
    age: {
        type: Number,
        default: 0,
        validate(value) {
            if(value < 13){
                throw new Error('You must be over the age of 13 to register for this site!')
            }
        }
    },
    email: {
        type: String,
        unique: true,
        required: true,
        trim: true,
        lowercase: true,
        validate(value){
            if (!validator.isEmail(value)) {
                throw new Error('Email is invalid')
            }
        }
    },
    password: {
        type: String,
        required: true,
        trim: true,
        minlength: 7,
        validate(value){
            if (value.toLowerCase().includes('password')) {
                throw new Error('Password cannot contain "password"')
            }
        }
    },
    tokens: [{
        token: {
            type: String,
            required: true
        }
    }]
})

userSchema.virtual('tasks', {
    ref: 'Task',
    localField: '_id',
    foreignField: 'owner'
})

userSchema.methods.generateAuthToken = async function () {
    const user = this
    const token = jwt.sign({ _id: user._id.toString() }, 'thisismynewcourse')

    user.tokens = user.tokens.concat({ token })
    await user.save()

    return token
}

userSchema.statics.findByCredentials = async (email, password) => {
    const user = await User.findOne({ email })

    if (!user) {
        throw new Error('Unable to login')
    }

    const isMatch = await bcrypt.compare(password, user.password)

    if (!isMatch) {
        throw new Error('Unable to login')
    }

    return user
}

//Hash the plain text password before saving
userSchema.pre('save', async function(next) {
    const user = this

    if (user.isModified('password')) {
        user.password = await bcrypt.hash(user.password, 8)
    }

    next()
})

userSchema.methods.toJSON = function () {
    const user = this
    const userObject = user.toObject()

    delete userObject.password
    delete userObject.tokens

    return userObject
}

const User = mongoose.model('User', userSchema)

module.exports = User

我正在尝试磨练的确切区域是年龄部分,我正在尝试验证 13 岁或以上的年龄,当我通过邮递员运行测试用户创建时,它会正确执行验证,但是它通过以下方式停止应用程序:

UnhandledPromiseRejectionWarning: ValidationError: User validation failed: age: You must be over the age of 13 to register

有没有办法可以防止应用程序崩溃,或者我应该在其他地方执行验证?提前致谢。

【问题讨论】:

    标签: node.js mongodb mongoose-schema


    【解决方案1】:

    通常在另一个文件中执行验证。这可以被认为是一种服务。但如果你想正确地做,它应该首先通过一个控制器。这是我制作的简单博客文章模式的示例。每次我将它发送到数据库之前,您都可以看到底部的函数运行。

    这就是它在我的架构文件中的样子,它位于名为 models 的文件夹中。

    // Requiring modules
    const mongoose = require('mongoose');
    
    // Initializing Schema
    var Schema = mongoose.Schema;
    
    // Creating a data model
    const schema = new Schema({
        shopname : {type: String, required:true},
        address : {type: String, required:true},
        review : {type: String, required:false},
    
        image : {type: String, required:false},
        originalname: {type: String, required:false},
        filename: {type: String, required:false},
        mimetype: {type: String, required:false},
        size : {type: String, required:false},
    
        updatedAt: {type: Date, required:false},
        createdAt: {type: Date, required:false}
    })
    
    // Settings up the process before the data is sent to mongoDB.
    // This process is call everytime 'save' is called.
    // it sets the data for createdAt and updatedAt.
    schema.pre('save', function(next){
        if (!this.createdAt){
            this.createdAt = new Date();
        }else{
            this.updatedAt = new Date();
        }
        next();
    })
    
    // Exports module
    module.exports = mongoose.model("Blog", schema);
    

    【讨论】:

    • 出于好奇,我如何从那里将该错误传递给用户,或者我应该在用户路由器文件中执行此操作?
    • 我会在前端做(这将是最简单的方法)!如果不能在那里完成,我会在路由器文件中完成。您可以使用 Express-flash 来实现此目的。 npmjs.com/package/express-flash 阻止应用程序崩溃的最简单方法是使用 try & catch 方法。你可以在这里阅读更多信息>>>> w3schools.com/js/js_errors.asp
    • 我在路由器文件中的 try catch 中尝试了它,我有一个 if else 语句,如果 user.age 上的年龄不大于 13,它不应该运行。但由于某种原因,它仍然会生成用户。任何阻止这种情况的方法,我正在阅读文档以查看是否可以找到阻止它的方法。
    • 是的,这里有一个例子router.post('/users', async (req, res) =&gt; { const user = new User(req.body) const token = await user.generateAuthToken() try { if (user.age &lt; 13) { return res.status(400).send('You must be over the age of 13 to join this site!') } else { await user.save() res.status(201).send({ user, token }) } }catch (e) { res.status(400).send(e) } }) 这个代码块有点乱,但我不太清楚如何发布它。
    • 嗯我试过你的代码,它似乎对我来说很好用!你能检查一下你在 user.age 变量中收到了什么吗?也许 console.log 并检查一下。我怀疑那里有问题
    猜你喜欢
    • 2020-10-06
    • 1970-01-01
    • 2015-10-21
    • 2016-06-04
    • 2011-08-24
    • 2014-05-03
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    相关资源
    最近更新 更多