javascript - 使用 joi 验证整个请求对象

标签 javascript node.js express joi

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

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

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

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

// other routes

在执行 Controller 之前,我使用策略来验证参数和正文。我的用户政策模块是

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 调用此路由时,出现此错误

message: '"userId" is required'

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


编辑:

我知道我可以验证 req.params 但如果我想更新用户怎么办?我将不得不验证参数 (userId) 和正文 (name, age, ...)

最佳答案

您的 joi 验证模式应该反射(reflect) 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

关于javascript - 使用 joi 验证整个请求对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55261182/

相关文章:

javascript - 从 VBA 转换为 JS - 输出错误

javascript - 异步递归在用于轮询 fn 的 Js 代码中是否安全

javascript - http.createServer 方法中添加选项参数的用例是什么

javascript - Express 4 - 如何正确提供来自其他文件的路由

javascript - 侧边栏自定义中的 Woocommerce 产品小部件

javascript - 根据视口(viewport)高度动态添加内容到引用的 React 子级

javascript - TypeError [ERR_INVALID_ARG_TYPE] : The "data" argument must be of type string or an instance of Buffer, TypedArray,或DataView

javascript - Restify 中间件就像指定路由的 Express 中间件一样

node.js - 如何在node.js、mongoose 中使用填充数据?

javascript - Express Router 对一个 url 的 post 方法返回 404