【问题标题】:validate the whole request object with joi使用 joi 验证整个请求对象
【发布时间】:2019-08-11 04:07:16
【问题描述】:

我创建了一个中间件,在调用控制器逻辑之前验证请求输入。

假设我有一个“通过 id 获取用户” - 路由

const usersController = require('../controllers/users.js');
const usersControllerPolicy = require('../policies/users.js');

router.get('/:userId', usersControllerPolicy.getUserById, usersController.getUserById);

// other routes

在执行控制器之前,我使用策略来验证参数和主体。我的用户政策模块是

const joi = require('joi');
const schemaValidation = require('../middleware/schemaValidation.js');

module.exports = {
    getUserById: (req, res, next) => {
        schemaValidation({
            userId: joi.string().guid().required()
        }, req, res, next);
    }

    // other routes
}

userId 是路由参数,而不是正文中的变量。这 schemaValidation 中间件验证给定架构并调用 next() 或发送 400 响应。

const joi = require('joi');
const requestResponder = require('../helpers/requestResponder.js');

module.exports = (schema, req, res, next) => {
    const { error } = joi.validate(req, schema);

    if (error)
        return requestResponder.sendBadRequestError(res);

    next();
}

当我使用 /users/137eaa6f-75c2-46f0-ba7c-c196fbfa367f 调用此路由时,我收到此错误

消息:'“userId”是必需的'

但验证应该没问题。我通过记录req.params 检查了验证joi.validate(req, schema),并且用户ID 可用。我错过了什么?


编辑:

我知道我可以验证req.params,但如果我想更新用户怎么办?我必须验证参数(userId)和正文(姓名,年龄,...)

【问题讨论】:

  • 如果userIDreq.params 中可用,那么您是否应该验证req.params?例如joi.validate(req.params, schema)
  • @Igor 是的,但我需要验证参数和正文。我将 userId 作为参数传入,但正文中也可能有要验证的变量。

标签: javascript node.js express joi


【解决方案1】:

您的 joi 验证模式应该反映 req 对象结构,应该可以工作:

const joi = require('joi');
const schemaValidation = require('../middleware/schemaValidation.js');

module.exports = {
    getUserById: (req, res, next) => {
        schemaValidation(joi.object({
            params: joi.object({
                userId: joi.string().guid().required()
            }).unknown(true)
        }).unknown(true), req, res, next);
    }

    // other routes
}

当您需要同时验证正文和参数时:

const joi = require('joi');
const schemaValidation = require('../middleware/schemaValidation.js');

const paramsValidation = joi.object({
    userId: joi.string().guid().required()
}).unknown(true);

const bodyValidation = joi.object({
    name: joi.string().required()
}).unknown(true);

module.exports = {
    getUserById: (req, res, next) => {
        schemaValidation(joi.object({
            params: paramsValidation,
            body: bodyValidation
        }).unknown(true), req, res, next);
    }

    // other routes
}

但我宁愿使用 3 个 joi 模式(正文、参数、查询)分别验证它们,例如这是怎么做到的https://www.npmjs.com/package/express-joi-validation#validation-ordering

【讨论】:

  • 很抱歉,您的第一种方法不起作用。你介意为多个模式提供一个 sn-p 吗?我不使用 express-joi-validation 并且没有得到它会如何完成
  • 我更新了答案中的第二个示例,应该可以使用
  • 您是否将 body-parser 包含在您的 express 应用程序中? const bodyParser = require('body-parser'); app.use(bodyParser.json()); > stackoverflow.com/questions/51231946/…
  • 我更新了我的答案,可能你必须在你的 joi 对象上添加.unknown(true)。如果它不起作用,请在此处提供错误输出:const { error } = joi.validate(req, schema);
猜你喜欢
  • 2020-06-30
  • 2018-02-27
  • 2021-10-10
  • 1970-01-01
  • 1970-01-01
  • 2016-10-11
  • 2017-08-05
  • 1970-01-01
  • 2020-07-13
相关资源
最近更新 更多