首页 > 解决方案 > JOI.validate() 不允许“dataValues”

问题描述

这是User带有 JOI (14.3) 验证的模型代码。该代码在创建新用户时可以正常工作,但最近似乎得了流感并抛出以下错误xxx not allowed

require('dotenv').config({path: process.cwd() +'\\config\\.env'});
const jwt = require('jsonwebtoken');
const moment = require('moment');
const Joi = require('joi');
const Sql = require('sequelize');
const db = require("../startup/db");

const User = db.define('user', {
    name: {type: Sql.STRING,
           allowNull: false,
           min: 2,
           max: 50,
    },
    email: {type: Sql.STRING,
            isEmail: true
    },      
    cell: {type: Sql.STRING,
            allowNull: false,
            min: 10,
            max: 20,
    },
    cell_country_code: {type: Sql.STRING,
                        allowNull: false
    },
    comp_name: {type: Sql.STRING
    },
    status: {type: Sql.STRING,
             allowNull: false,
             isIn: ['active', 'blocked', 'inactive', 'pending', 'unverified']
    },
    role: {type: Sql.STRING,
           allowNull: false
    },
    device_id: {type: Sql.STRING,   //maybe empty when the user is initially created.
    },
    user_data: {type: Sql.JSONB
    },
    last_updated_by_id: {type: Sql.INTEGER},
    fort_token: {type: Sql.STRING,
                 allowNull: false,
                 min: 20  //64 for production
    },
    createdAt: Sql.DATE,
    updatedAt: Sql.DATE
  }, {

    indexes: [
      { 
        //For same fort_token, name to be unique
        unique: true,
        fields: ['name', 'fort_token']
      }, {
        //unique cell
        //unique: true,
        fields: ['cell_country_code', 'cell', 'status']
      }, {
        fields: ['cell_country_code', 'cell']
      }, {
        //email
        fields: ['email']
      }, {
        fields: ['device_id']
      }, {
        fields: ['status']
      }, {
        fields: ['fort_token']
      }
    ]   

  });

function validateUser(user) {
    const schema = {
        name: Joi.string()
        .min(2)
        .max(50)
        .required()
        .trim(),
    cell: Joi.string()
        .min(10)
        .max(20)
        .trim()
        .required()
        .error(new Error('该手机号有误!')),
    cell_country_code: Joi.string()
        .trim()
        .required(),
    role: Joi.string()
        .required()
        .trim(),
    email: Joi.string()
        .email()
        .allow("")
        .optional()
    };

    return Joi.validate(user, schema);
};

这是错误:

new user data :  { _device_id: '8c9c25711c7d0262',
  cell: '8008006414 ',
  cell_country_code: '1',
  name: 'ss9',
  corp_name: '',
  role: 'eventer',
  email: '',
  user_data: { avatar: '' } }
error in user validate :  { ValidationError: "dataValues" is not allowed. "_previousDataValues" is not allowed. "_changed" is not allowed. "_modelOptions" is not allowed. "_options" is not allowed. "isNewRecord" is not allowed
    at Object.exports.process (C:\d\code\js\emps_bbone\node_modules\joi\lib\errors.js:203:19)
    at internals.Object._validateWithOptions (C:\d\code\js\emps_bbone\node_modules\joi\lib\types\any\index.js:764:31)
    at module.exports.internals.Any.root.validate (C:\d\code\js\emps_bbone\node_modules\joi\lib\index.js:147:23)
    at validateUser (C:\d\code\js\emps_bbone\models\user.js:106:16)
    at router.post (C:\d\code\js\emps_bbone\routes\users.js:217:27)
    at newFn (C:\d\code\js\emps_bbone\node_modules\express-async-errors\index.js:16:20)
    at Layer.handle [as handle_request] (C:\d\code\js\emps_bbone\node_modules\express\lib\router\layer.js:95:5)
    at next (C:\d\code\js\emps_bbone\node_modules\express\lib\router\route.js:137:13)
    at C:\d\code\js\emps_bbone\middleware\auth_role.js:7:7
    at newFn (C:\d\code\js\emps_bbone\node_modules\express-async-errors\index.js:16:20)
    at Layer.handle [as handle_request] (C:\d\code\js\emps_bbone\node_modules\express\lib\router\layer.js:95:5)
    at next (C:\d\code\js\emps_bbone\node_modules\express\lib\router\route.js:137:13)
    at module.exports (C:\d\code\js\emps_bbone\middleware\auth_userinfo.js:106:13)
  isJoi: true,
  name: 'ValidationError',
  details:
   [ { message: '"dataValues" is not allowed',
       path: [Array],
       type: 'object.allowUnknown',
       context: [Object] },
     { message: '"_previousDataValues" is not allowed',
       path: [Array],
       type: 'object.allowUnknown',
       context: [Object] },
     { message: '"_changed" is not allowed',
       path: [Array],
       type: 'object.allowUnknown',
       context: [Object] },
     { message: '"_modelOptions" is not allowed',
       path: [Array],
       type: 'object.allowUnknown',
       context: [Object] },
     { message: '"_options" is not allowed',
       path: [Array],
       type: 'object.allowUnknown',
       context: [Object] },
     { message: '"isNewRecord" is not allowed',
       path: [Array],
       type: 'object.allowUnknown',
       context: [Object] } ],
  _object:
   user {
     dataValues:
      { id: null,
        name: 'ss9',
        cell: '8008006414',
        cell_country_code: '1',
        email: '',
        role: 'eventer' },
     _previousDataValues:
      { name: undefined,
        cell: '8008006414 ',
        cell_country_code: undefined,
        email: undefined,
        role: undefined },
     _changed:
      { name: true,
        cell: true,
        cell_country_code: true,
        email: true,
        role: true },
     _modelOptions:
      { timestamps: true,
        validate: {},
        freezeTableName: false,
        underscored: false,
        paranoid: false,
        rejectOnEmpty: false,
        whereCollection: [Object],
        schema: null,
        schemaDelimiter: '',
        defaultScope: {},
        scopes: {},
        indexes: [Array],
        name: [Object],
        omitNull: false,
        sequelize: [Sequelize],
        hooks: {} },
     _options: { isNewRecord: true, _schema: null, _schemaDelimiter: '' },
     isNewRecord: true },
  annotate: [Function] }
error in new user

下面是创建新用户的代码:

try {
        user = new User(_.pick(req.body, ["name", "cell", "cell_country_code", "email", "role" ]));
        const { error } = validateUser(user);  //<<====== throws error with JOI.validate()
        console.log("error in user validate : ", error);
        if (error) {console.log("error in new user "); return res.status(400).send(error.details[0].message)};

我不知道验证错误是关于什么的。

标签: node.jssequelize.jsjoi

解决方案


您需要传递带有“allowUnknown:true”的选项作为验证函数的第三个参数

https://github.com/hapijs/joi/blob/v15.0.3/API.md#validatevalue-schema-options-callback


推荐阅读